Redis主從數(shù)據(jù)同步

Redis作為一個(gè)分布式的存儲(chǔ)服務(wù),集群的工作模式幾乎是標(biāo)配邪蛔,Redis目前的主從模式也是大多人使用的模型急黎,那Redis的主機(jī)和從機(jī)是如何保證數(shù)據(jù)同步一致的呢?

RDB 與 AOF 文件

Redis本身侧到,數(shù)據(jù)的持久化有兩種形式勃教,一種是AOF,另一種就是RDB文件的格式匠抗,作為主從同步的模型故源,Redis采用的就是RDB的文件格式。這里簡(jiǎn)單介紹一下RDB 和 AOF汞贸。

AOF

這種存儲(chǔ)模式非常高效绳军,他所存儲(chǔ)的是Redis本身執(zhí)行的所有寫命令,比如說set key value, 所有的寫相關(guān)的命令矢腻,都會(huì)被加載到AOF里面门驾。

但是有兩點(diǎn)點(diǎn)要注意一下:

  1. 寫入文件的過程不是實(shí)時(shí)的,畢竟寫入文件是有性能消耗的多柑,所以會(huì)有一個(gè)AOF緩沖區(qū)來存儲(chǔ)最近的操作奶是,然后定時(shí)寫入文件。
  2. 對(duì)于一些命令竣灌,比如說反復(fù)對(duì)list的操作诫隅,結(jié)果集會(huì)越來越大,極端的例子是我們for循環(huán)一組數(shù)據(jù)帐偎,逐一添加到list里面,對(duì)于AOF來說蛔屹,就是幾千條命令削樊,所以AOF會(huì)有一個(gè)重寫的過程,具體的內(nèi)容在這里不介紹了,可以參閱官網(wǎng)和相關(guān)書籍漫贞。

RDB

相較于AOF的快照行為甸箱,RDB是對(duì)于內(nèi)存中的數(shù)據(jù),直接進(jìn)行一次壓縮和文件寫入的過程迅脐,這種形式還原數(shù)據(jù)對(duì)于Redis來說芍殖,比AOF要快很多,但是對(duì)于生成來講谴蔑,可能性能就不盡如人意了豌骏,他是將數(shù)據(jù),按照對(duì)應(yīng)的類型(string隐锭,list窃躲,set,map钦睡,zset)按照特定的格式蒂窒,存入文件里面,添加一些版本號(hào)和唯一標(biāo)示荞怒,來識(shí)別RDB文件洒琢。

生成的命令有兩種,一個(gè)是SAVE褐桌,一個(gè)是BGSAVE, 區(qū)別就是前者是整個(gè)Redis不工作來生成數(shù)據(jù)衰抑,后者是開啟另一個(gè)線程來處理,不影響Redis的正常工作撩嚼。但同樣的是RDB文件生成的時(shí)候停士,性能低下,注定他不能實(shí)時(shí)存儲(chǔ)完丽,通常情況下都是設(shè)置一些條件觸發(fā)生成操作恋技。這里篇幅有限,以后有機(jī)會(huì)再慢慢介紹逻族。

兩者對(duì)比

  1. 首先第一點(diǎn)蜻底,AOF存儲(chǔ)的是操作,而RDB存儲(chǔ)的是實(shí)際的數(shù)據(jù)庫(kù)內(nèi)容聘鳞,所以注定的是存儲(chǔ)上薄辅,AOF肯定更加便捷,RDB更加耗費(fèi)性能抠璃。但相反的是站楚,對(duì)于大量數(shù)據(jù),RDB還原的速度就快很多了搏嗡,而AOF由于包含了大量的命令窿春,需要逐一執(zhí)行拉一,整個(gè)過程對(duì)于Redis而言,肯定不如RDB來得好旧乞。

  2. 數(shù)據(jù)丟失的問題上蔚润,RDB由于不是實(shí)時(shí)的,所以注定的在宕機(jī)的時(shí)候尺栖,會(huì)有一段時(shí)間空隙嫡纠,數(shù)據(jù)會(huì)產(chǎn)生丟失的情況,而AOF采用的是緩沖區(qū)的形式延赌,后臺(tái)線程進(jìn)行AOF重寫除盏,所以緩沖區(qū)也有可能因?yàn)殄礄C(jī)而存在丟失的問題,但是對(duì)比于RDB皮胡,肯定丟失的情況更加少痴颊。

主從同步的基本原理

聊了文件存儲(chǔ)之后,回到主題上面屡贺,Redis的主從模式采用的是RDB文件同步的方式蠢棱,因?yàn)镽edis的服務(wù)端,數(shù)據(jù)量有可能非常的大甩栈,所以從性能考慮泻仙,沒有采用AOF快照來同步。

過程大概如下:

  1. 從機(jī)上線量没,主動(dòng)鏈接主機(jī)玉转,發(fā)送SYNC命令
  2. 主機(jī)接到命令后,執(zhí)行BGSAVE命令殴蹄,生成RDB文件
  3. 主機(jī)向從機(jī)發(fā)送RDB文件究抓,開始同步數(shù)據(jù)
  4. 同步之后,主機(jī)將最近的更新袭灯,采用命令的形式同步到從機(jī)上面刺下。

舊版復(fù)制的缺陷

上述的過程對(duì)于一個(gè)從機(jī),新加入到集群里面的時(shí)候稽荧,比較合適橘茉,但是如果因?yàn)閿嗑€重連,則需要重新復(fù)制主機(jī)上所有的內(nèi)容姨丈,主機(jī)也因此要進(jìn)行一次全量級(jí)的RDB畅卓,比較耗費(fèi)性能。

在2.8版本之后蟋恬,采用了一個(gè)新的增量復(fù)制的過程翁潘,流程如下:

  1. 前面的sync的過程還是一樣,沒有差異
  2. 當(dāng)從機(jī)斷線重連之后歼争,會(huì)發(fā)送PSYNC,要求增量同步唐础,并包括一個(gè)offset
  3. 主機(jī)根據(jù)offset的位置箱歧,對(duì)之后的數(shù)據(jù)進(jìn)行一次增量同步,到從機(jī)上面

這里面的offset是由主機(jī)和從機(jī)共同維護(hù)的一膨,相當(dāng)于一個(gè)樂觀鎖,描述了兩方的版本差異洒沦。

那決定能否增量同步的主要因素豹绪,包括如下三個(gè):

  1. 是否具備偏移量,與主機(jī)進(jìn)行對(duì)比
  2. 主服務(wù)器的復(fù)制積壓緩沖區(qū)(Replication backlog)
  3. 從服務(wù)器的ID

第一條不難理解申眼,重點(diǎn)解釋一下第二和第三條

復(fù)制積壓緩沖區(qū)

Redis每分鐘都會(huì)處理很多的數(shù)據(jù)瞒津,不可能一直把更新的操作存起來,等待從機(jī)上線在傳輸括尸,AOF也不是都在內(nèi)存中一直保存巷蚪,所以Redis有一個(gè)緩沖區(qū),采用隊(duì)列的模式來存儲(chǔ)這些寫操作濒翻。

所有的更新操作以隊(duì)列的形式放入里面屁柏,內(nèi)存大小默認(rèn)是1MB,超過1MB之后有送,前面進(jìn)入隊(duì)列的寫操作就會(huì)被移除淌喻。

所以當(dāng)從機(jī)上線之后,如果offset與主機(jī)版本差距的內(nèi)容還在緩沖區(qū)內(nèi)雀摘,則可以從緩沖區(qū)進(jìn)行增量同步裸删。否則依然還是全量同步(RDB),這里就好比你的機(jī)器宕機(jī)了一天阵赠,在上線涯塔,你不能要求我把這一天的數(shù)據(jù)都給你吧,你直接全量同步得了清蚀。

這里我就想到了一個(gè)問題匕荸,如果我們反復(fù)對(duì)Redis更新特別大的K-V的話,超過1M轧铁,會(huì)使得這個(gè)緩沖區(qū)失效每聪,因?yàn)槊看蔚母露汲^這個(gè)緩沖區(qū)大小了,所以同步操作對(duì)于從機(jī)來說齿风,都是全量同步药薯,如果太頻繁的話,則會(huì)產(chǎn)生很大的問題救斑。

當(dāng)然這個(gè)緩沖區(qū)的大小也是可以設(shè)置調(diào)整的餓童本,可以根據(jù)需求配置。

從服務(wù)器ID

這個(gè)不難理解脸候,因?yàn)镽edis有一個(gè)Slot的概念穷娱,每個(gè)機(jī)器負(fù)責(zé)一部分的Key绑蔫,所以如果你之前不是我的從機(jī),那你內(nèi)存內(nèi)的數(shù)據(jù)肯定都不是我的值泵额,就不能只看offset了配深,還要看一下你之前是不是我的從機(jī),這里主機(jī)會(huì)維護(hù)從機(jī)的唯一ID嫁盲,來校驗(yàn)篓叶。

整個(gè)復(fù)制流程

1. 設(shè)置端口號(hào)進(jìn)行連接

SLAVEOF master_ip master_port 命令,或者通過配置文件配置均可羞秤。

2. 建立套接字連接

建立連接之后缸托,從服務(wù)器會(huì)負(fù)責(zé)處理后續(xù)的RDB文件和寫命令,主服務(wù)器將從服務(wù)器作為一個(gè)客戶端進(jìn)行響應(yīng)

3. 發(fā)送PING請(qǐng)求

連接之后瘾蛋,通過PING請(qǐng)求檢查相互的狀態(tài)俐镐,類似心跳校測(cè)的內(nèi)容。

4. 身份驗(yàn)證

這里需要主服務(wù)器和從服務(wù)器都設(shè)置校驗(yàn)選項(xiàng)哺哼,然后校驗(yàn)密碼佩抹。

  • 如果兩方都沒有設(shè)置,則這一步可以忽略
  • 如果從服務(wù)器設(shè)置了幸斥,主服務(wù)沒有設(shè)置匹摇,則會(huì)返回 no password is set
  • 如果都設(shè)置了,則會(huì)進(jìn)行驗(yàn)證
  • 如果主服務(wù)器設(shè)置了甲葬,但是從服務(wù)器沒有設(shè)置廊勃,則會(huì)返回NOAUTH

5. 發(fā)送端口

由于從服務(wù)類似于客戶端,等待接受信息经窖,所以需要告知主服務(wù)器自己接受所用的端口號(hào)坡垫,方便未來接受RDB和寫命令。

6. 同步

這個(gè)時(shí)候就進(jìn)入到我們上面描述的同步機(jī)制里面了画侣,SYNC or PSYNC 等等的內(nèi)容冰悠。

7. 命令傳播

后續(xù)的寫命令,都會(huì)通過上面配置的端口號(hào)不停傳輸配乱。

其他內(nèi)容

心跳檢測(cè)

進(jìn)行了套接字連接溉卓,執(zhí)行過PING命令之后,雖然保證了連接搬泥,但是后續(xù)的寫同步操作桑寨,依然需要實(shí)時(shí)連接。所以從服務(wù)器會(huì)定期發(fā)送自己的offset到主服務(wù)器上忿檩,檢測(cè)是否需要同步寫操作尉尾。

檢測(cè)從服務(wù)狀態(tài)

主服務(wù)器在一個(gè)時(shí)間周期內(nèi)沒有收到從服務(wù)器上述的心跳檢測(cè)內(nèi)容,則察覺從服務(wù)器可能異常了燥透,所以這個(gè)時(shí)候會(huì)需要查看從服務(wù)器的信息沙咏。

Redis會(huì)配置一些拒絕寫操作的內(nèi)容辨图,在一些特定情況下會(huì)認(rèn)為寫操作不安全,這里的不安全是通過配置決定的:

  1. min-slaves-to-write 3
  2. min-slaves-max-lag 10

以上的信息表示從節(jié)點(diǎn)不能少于3個(gè)肢藐,或者3個(gè)從服務(wù)延遲不能超過10秒故河。否則拒絕寫操作,只執(zhí)行讀操作吆豹。

命令丟失

由于定期的心跳檢測(cè)的存在忧勿,所以定期檢測(cè)版本,發(fā)現(xiàn)消息丟失這種內(nèi)容就自動(dòng)實(shí)現(xiàn)了瞻讽,可以通過offset準(zhǔn)確的了解到從服務(wù)器哪些信息沒有接受到,及時(shí)的作出響應(yīng)熏挎。

感謝

以上內(nèi)容參考Redis官方網(wǎng)站速勇,以及《Redis的設(shè)計(jì)與實(shí)現(xiàn)》一書,如有紕漏坎拐,歡迎指出烦磁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市哼勇,隨后出現(xiàn)的幾起案子都伪,更是在濱河造成了極大的恐慌,老刑警劉巖积担,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陨晶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡帝璧,警方通過查閱死者的電腦和手機(jī)先誉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來的烁,“玉大人褐耳,你說我怎么就攤上這事】是欤” “怎么了铃芦?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)襟雷。 經(jīng)常有香客問我刃滓,道長(zhǎng),這世上最難降的妖魔是什么嗤军? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任注盈,我火速辦了婚禮,結(jié)果婚禮上叙赚,老公的妹妹穿的比我還像新娘老客。我一直安慰自己僚饭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布胧砰。 她就那樣靜靜地躺著鳍鸵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尉间。 梳的紋絲不亂的頭發(fā)上偿乖,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音哲嘲,去河邊找鬼贪薪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛眠副,可吹牛的內(nèi)容都是我干的画切。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼囱怕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼霍弹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起娃弓,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤典格,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后台丛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耍缴,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年齐佳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了私恬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炼吴,死狀恐怖本鸣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情硅蹦,我是刑警寧澤荣德,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站童芹,受9級(jí)特大地震影響涮瞻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜假褪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一署咽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦宁否、人聲如沸窒升。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饱须。三九已至,卻和暖如春台谊,著一層夾襖步出監(jiān)牢的瞬間蓉媳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工锅铅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酪呻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓盐须,卻偏偏與公主長(zhǎng)得像号杠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丰歌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一、Redis高可用概述 在介紹Redis高可用之前屉凯,先說明一下在Redis的語(yǔ)境中高可用的含義立帖。 我們知道,在w...
    空語(yǔ)閱讀 1,597評(píng)論 0 2
  • 企業(yè)級(jí)redis集群架構(gòu)的特點(diǎn) 海量數(shù)據(jù) 高并發(fā) 高可用 要達(dá)到高可用悠砚,持久化是不可減少的晓勇,持久化主要是做災(zāi)難恢復(fù)...
    lucode閱讀 2,205評(píng)論 0 7
  • 數(shù)據(jù)庫(kù) 多數(shù)據(jù)庫(kù)結(jié)構(gòu) 一個(gè)Redis實(shí)例可以支持多個(gè)數(shù)據(jù)庫(kù),當(dāng)客戶端與服務(wù)端連接并指定到某個(gè)數(shù)據(jù)庫(kù)時(shí)灌旧,兩者的結(jié)構(gòu)如...
    宇宙最強(qiáng)架構(gòu)師閱讀 612評(píng)論 0 3
  • 基于內(nèi)存的NoSQL數(shù)據(jù)庫(kù)绑咱。提供五種數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。字符串枢泰、列表描融、集合、有序集合衡蚂、散列表窿克。Redis 支持很多特性...
    韓絕交閱讀 689評(píng)論 0 1
  • 一個(gè)國(guó)家年叮、一個(gè)民族的強(qiáng)盛,總是以文化興盛為支撐的玻募。沒有文明的繼承和發(fā)展只损,沒有文化的弘揚(yáng)和繁榮,就沒有中國(guó)夢(mèng)的實(shí)現(xiàn)七咧。...
    y飛舞的燕子y閱讀 461評(píng)論 0 1