真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

分布式Redis深度歷險(xiǎn)-復(fù)制

redis深度歷險(xiǎn)分為兩個(gè)部分,單機(jī)Redis和分布式Redis。

“專(zhuān)業(yè)、務(wù)實(shí)、高效、創(chuàng)新、把客戶(hù)的事當(dāng)成自己的事”是我們每一個(gè)人一直以來(lái)堅(jiān)持追求的企業(yè)文化。 創(chuàng)新互聯(lián)是您可以信賴(lài)的網(wǎng)站建設(shè)服務(wù)商、專(zhuān)業(yè)的互聯(lián)網(wǎng)服務(wù)提供商! 專(zhuān)注于成都做網(wǎng)站、成都網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、設(shè)計(jì)服務(wù)業(yè)務(wù)。我們始終堅(jiān)持以客戶(hù)需求為導(dǎo)向,結(jié)合用戶(hù)體驗(yàn)與視覺(jué)傳達(dá),提供有針對(duì)性的項(xiàng)目解決方案,提供專(zhuān)業(yè)性的建議,創(chuàng)新互聯(lián)建站將不斷地超越自我,追逐市場(chǎng),引領(lǐng)市場(chǎng)!

本文為分布式Redis深度歷險(xiǎn)系列的第一篇,主要內(nèi)容為Redis的復(fù)制功能。

Redis的復(fù)制功能的作用和大多數(shù)分布式存儲(chǔ)系統(tǒng)一樣,就是為了支持主從設(shè)計(jì),主從設(shè)計(jì)的好處有以下幾點(diǎn):

  • 讀寫(xiě)分離,提高讀寫(xiě)性能

  • 數(shù)據(jù)備份,減少數(shù)據(jù)丟失的風(fēng)險(xiǎn)

  • 高可用,避免單點(diǎn)故障

分布式Redis深度歷險(xiǎn)-復(fù)制

舊版復(fù)制實(shí)現(xiàn)

Redis的復(fù)制主要分為同步和命令傳播兩個(gè)步驟:

同步可以理解為全量,是將主服務(wù)器某一時(shí)刻的所有數(shù)據(jù)全部同步到從服務(wù)器。

命令傳播可以理解為增量,當(dāng)主服務(wù)器數(shù)據(jù)被修改時(shí),主服務(wù)器向從服務(wù)器發(fā)送對(duì)應(yīng)的數(shù)據(jù)修改命令。

?

同步

同步分為以下幾個(gè)步驟:

1.從服務(wù)器向主服務(wù)器發(fā)送SYNC命令(執(zhí)行SLAVE OF命令的第一步也會(huì)執(zhí)行SYNC

2.主服務(wù)器在收到從服務(wù)器命令時(shí),會(huì)執(zhí)行BGSAVE,也就是新開(kāi)一個(gè)子進(jìn)程將內(nèi)存中的數(shù)據(jù)保存到RDB文件中。同時(shí)使用一個(gè)內(nèi)存緩沖區(qū)記錄從現(xiàn)在開(kāi)始執(zhí)行的寫(xiě)命令,該內(nèi)存緩沖區(qū)的作用就是記錄RDB文件生成期間的增量。

3.向從服務(wù)器發(fā)送RDB文件

4.將緩沖區(qū)中的寫(xiě)命令發(fā)送給從服務(wù)器

同步可以分為兩種情況,一種是從服務(wù)器第一次連接主服務(wù)器,另一種是從服務(wù)與主服務(wù)器的網(wǎng)絡(luò)鏈接斷開(kāi)了,重新連上主服務(wù)器并重新同步。

?

命令傳播

命令傳播實(shí)現(xiàn)邏輯比較簡(jiǎn)單,當(dāng)主服務(wù)器執(zhí)行了寫(xiě)命令后,為了保證從服務(wù)器與主服務(wù)器數(shù)據(jù)的一致性,主服務(wù)器會(huì)將寫(xiě)命令發(fā)送給從服務(wù)器,從服務(wù)器執(zhí)行完收到的寫(xiě)命令后其數(shù)據(jù)就能和主服務(wù)器保持一致了(當(dāng)然會(huì)有延時(shí)),注意,從服務(wù)器對(duì)于客戶(hù)端來(lái)說(shuō)是只讀的,因此從服務(wù)器的所有數(shù)據(jù)都是來(lái)自于主服務(wù)器的同步or命令傳播。

?

舊版復(fù)制存在的問(wèn)題

假設(shè)Redis主從服務(wù)器之間的網(wǎng)絡(luò)環(huán)境不太可靠,我們來(lái)看看上述復(fù)制方法會(huì)出現(xiàn)什么問(wèn)題。假設(shè)有主服務(wù)器A和從服務(wù)器B,主服務(wù)器中目前存在1-10000共一萬(wàn)條數(shù)據(jù)。

1.初始連接,從服務(wù)器第一次從主服務(wù)器同步數(shù)據(jù),同步完成后,從服務(wù)器也有1-10000共一萬(wàn)條數(shù)據(jù)。

2.主服務(wù)器新增10001,10002兩條數(shù)據(jù)

3.通過(guò)命令傳播,從服務(wù)器也新增10001,10002兩條數(shù)據(jù)

4.這時(shí)候主從服務(wù)器之間的網(wǎng)絡(luò)斷開(kāi)

5.主服務(wù)器新增數(shù)據(jù)10003,因?yàn)榫W(wǎng)絡(luò)斷開(kāi),所以從服務(wù)器感受不到數(shù)據(jù)變化

6.網(wǎng)絡(luò)恢復(fù),從服務(wù)器重新連接上主服務(wù)器,并發(fā)送SYNC命令,進(jìn)行同步操作

7.主服務(wù)器將所有數(shù)據(jù)發(fā)送給從服務(wù)器(1-10003)

從上述步驟中可以看到,當(dāng)從服務(wù)器重新連接上主服務(wù)器時(shí),會(huì)重新進(jìn)行全量同步,造成大量不必要的IO開(kāi)銷(xiāo),如果網(wǎng)絡(luò)環(huán)境不穩(wěn)定時(shí),會(huì)導(dǎo)致主服務(wù)器一直將內(nèi)存中的數(shù)據(jù)寫(xiě)到磁盤(pán)再發(fā)送給從服務(wù)器。

?

新版復(fù)制實(shí)現(xiàn)

為了解決老版復(fù)制問(wèn)題,Redis2.8對(duì)于復(fù)制功能進(jìn)行了優(yōu)化。實(shí)現(xiàn)如下:

1.主服務(wù)器會(huì)維護(hù)一個(gè)偏移量,每次向服務(wù)器傳播N個(gè)字節(jié)的數(shù)據(jù)時(shí),該偏移量就會(huì)加上N,比如說(shuō)一開(kāi)始是0,接受到一條set key1 value1后,其偏移量就為13(真實(shí)偏移可能不是13,只是舉個(gè)例子)。//這里可能要看下代碼確認(rèn)

2.從服務(wù)器也維護(hù)一個(gè)偏移量,當(dāng)從服務(wù)器收到到主服務(wù)器的N個(gè)字節(jié)數(shù)據(jù)時(shí),該偏移量會(huì)加上N。

3.主服務(wù)器維護(hù)一個(gè)固定大小的緩沖區(qū),每次接受到客戶(hù)端寫(xiě)命令后,都會(huì)將對(duì)應(yīng)命令往這個(gè)緩沖區(qū)寫(xiě)入。當(dāng)寫(xiě)入內(nèi)容超出固定大小后,會(huì)覆蓋原來(lái)的數(shù)據(jù)。

4.主服務(wù)器有一個(gè)唯一id

5.從服務(wù)器連接上主服務(wù)時(shí),會(huì)向主服務(wù)器發(fā)送上一次連接的主服務(wù)器的id以及偏移量,這里又分幾種情況:

  1. 如果從服務(wù)器沒(méi)傳id或者id與當(dāng)前主服務(wù)器不匹配,那主服務(wù)器將傳送全量數(shù)據(jù)

  2. 如果從服務(wù)器的offset在緩沖區(qū)中不能找到(落后太多導(dǎo)致緩沖區(qū)已經(jīng)被新數(shù)據(jù)覆蓋了),那也會(huì)進(jìn)行全量同步

  3. 如果offset能在緩沖區(qū)找到,則主服務(wù)從offset開(kāi)始,將緩沖區(qū)的數(shù)據(jù)依次發(fā)送給從服務(wù)器。(有做pipeline的優(yōu)化嗎)

以上就是新版復(fù)制的大致思路,要注意的是,主服務(wù)器緩沖區(qū)的大小設(shè)置很關(guān)鍵,如果設(shè)置的太大會(huì)導(dǎo)致空間浪費(fèi),如果太小會(huì)導(dǎo)致網(wǎng)絡(luò)環(huán)境不好時(shí),其退化為老版復(fù)制。

之前我就踩過(guò)這樣的坑:在上云時(shí),redis集群在兩個(gè)不同機(jī)房,主從之前網(wǎng)絡(luò)環(huán)境不太穩(wěn)定,而redis機(jī)器上存儲(chǔ)的value比較大,很容易就將緩沖區(qū)占滿(mǎn)導(dǎo)致每次全量同步,形成惡性循環(huán),從服務(wù)器落后不可讀,主服務(wù)器不可寫(xiě)(當(dāng)從Redis落后太多時(shí),主Redis將拒絕寫(xiě)入,具體參數(shù)可以配置的,下文還會(huì)提到)

所以建議將緩沖區(qū)大小設(shè)置為平均重連間隔*每秒寫(xiě)入數(shù)據(jù)量*2

?

主從心跳機(jī)制

從服務(wù)器默認(rèn)會(huì)每秒一次的頻率向主服務(wù)器發(fā)送心跳:
REPLCONF A?K ,
replication_offset代表從服務(wù)器當(dāng)前的復(fù)制偏移量。

心跳有三個(gè)作用:

1.檢測(cè)主從服務(wù)器的網(wǎng)絡(luò)連接

2.實(shí)現(xiàn)min-slaves功能

3.檢測(cè)命令丟失

?

檢測(cè)主從服務(wù)器的網(wǎng)絡(luò)連接

主服務(wù)器會(huì)記錄從服務(wù)器上次發(fā)送心跳是什么時(shí)間,根據(jù)這個(gè)時(shí)間,我們能知道主從服務(wù)器之間的連接是不是出現(xiàn)了故障

?

實(shí)現(xiàn)min-slaves功能

Redis為了保證數(shù)據(jù)的安全性,可以配置當(dāng)從服務(wù)器小于min-slaves-to-write個(gè)或者min-slaves-to-write個(gè)從服務(wù)器的延遲都大于等于min-slaves-max-lag時(shí),主服務(wù)器拒絕寫(xiě)。

?

檢測(cè)命令丟失

主從之間的復(fù)制,其實(shí)是以主服務(wù)器作為從服務(wù)器的客戶(hù)端來(lái)實(shí)現(xiàn)的(在Redis中,所有服務(wù)器之間的數(shù)據(jù)傳遞都是以該種方式)。假設(shè)主服務(wù)器向從服務(wù)器發(fā)送一條寫(xiě)命令,但網(wǎng)絡(luò)出現(xiàn)異常,從服務(wù)器并沒(méi)有收到該命令。


這就會(huì)導(dǎo)致數(shù)據(jù)不一致的狀態(tài)(你可能想主服務(wù)器發(fā)送命令時(shí),如果從沒(méi)返回失敗,進(jìn)行重發(fā)不就好了嗎?如果說(shuō)從成功執(zhí)行了命令,但是再回復(fù)主的時(shí)候出現(xiàn)了問(wèn)題,那主如果重發(fā)就會(huì)造成數(shù)據(jù)異常了)。所以主服務(wù)器會(huì)根據(jù)心跳信息來(lái)決定要發(fā)送的數(shù)據(jù)??磦€(gè)例子:

初始,主服務(wù)器和從服務(wù)器偏移量都是100。

主服務(wù)器收到客戶(hù)端的寫(xiě)命令,將偏移量改成110,同時(shí)向從服務(wù)器發(fā)送寫(xiě)命令,但因網(wǎng)絡(luò)原因,從服務(wù)器并沒(méi)有收到,其偏移量仍然是100。主服務(wù)器根據(jù)心跳發(fā)現(xiàn)從服務(wù)器的偏移量是100落后于自己,所以會(huì)將100-110的數(shù)據(jù)進(jìn)行重發(fā)。

?

看到這里,你可能對(duì)于上述方案的正確性感到質(zhì)疑:在從服務(wù)器接收到100-110的數(shù)據(jù)前,它發(fā)送心跳包告訴主服務(wù)器自己當(dāng)前偏移為100,然后接收到了100-110的數(shù)據(jù)。這時(shí)下個(gè)心跳還沒(méi)發(fā)出,主服務(wù)器認(rèn)為從服務(wù)器落后于自己,再次發(fā)送100-110的數(shù)據(jù),導(dǎo)致從服務(wù)器再次寫(xiě)入100-110的數(shù)據(jù),導(dǎo)致數(shù)據(jù)異常!

?

如果你有想到這個(gè)問(wèn)題,說(shuō)明你是有在認(rèn)真思考了~

其實(shí)是不存在這種情況的,原因是redis是單線(xiàn)程的!記住單線(xiàn)程三個(gè)字,再回頭看一遍問(wèn)題描述,相信你能想明白~

?


網(wǎng)站標(biāo)題:分布式Redis深度歷險(xiǎn)-復(fù)制
網(wǎng)站鏈接:http://weahome.cn/article/gcepjc.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部