Redis的單機(jī)模式不難,配置文件參數(shù)了解具體含義针余,設(shè)定業(yè)務(wù)上符合自己的就好了蛤高。
之前記錄了關(guān)于Redis的數(shù)據(jù)結(jié)構(gòu)和對象的知識(可以點(diǎn)Redis標(biāo)簽看看)森枪,下面開始填坑。
復(fù)制
在Redis中莫杈,用戶可以通過執(zhí)行SLAVEOF命令或者設(shè)置slaveof選項(xiàng)蛙婴,讓一個(gè)服務(wù)去復(fù)制(replicate)另一個(gè)服務(wù)器敷钾。被復(fù)制的服務(wù)器為主服務(wù)器(master)宣谈,另一個(gè)對主服務(wù)器進(jìn)行復(fù)制的服務(wù)器則被稱為從服務(wù)器(slave)
舉個(gè)??:(Redis版本是4.0.8)
在6379端口啟動(dòng)一個(gè)redis-server:
$ redis-server --port 6379
$ redis-cli -p 6379
127.0.0.1:6379>
在6380端口號啟動(dòng)一個(gè)redis-server愈犹,接著通過slaveof命令進(jìn)行復(fù)制
$ redis-server --port 6380
$ redis-cli -p 6380
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
在這里,6379是主服務(wù)器蒲祈,6380是從服務(wù)器甘萧。
接著能在6380的redis-server界面中看到日志:
19092:S 23 Mar 01:00:26.944 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
19092:S 23 Mar 01:00:26.945 * SLAVE OF 127.0.0.1:6379 enabled (user request from 'id=2 addr=127.0.0.1:60778 fd=8 name= age=50 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
19092:S 23 Mar 01:00:27.234 * Connecting to MASTER 127.0.0.1:6379
19092:S 23 Mar 01:00:27.234 * MASTER <-> SLAVE sync started
19092:S 23 Mar 01:00:27.234 * Non blocking connect for SYNC fired the event.
19092:S 23 Mar 01:00:27.246 * Master replied to PING, replication can continue...
19092:S 23 Mar 01:00:27.246 * Trying a partial resynchronization (request 2e56cf1343f6b2e864c968bd59b4a16ed78b8f1d:1).
19092:S 23 Mar 01:00:27.266 * Full resync from master: bf36b20c3942e91ac4f262a2afdc90970b2d7c54:0
19092:S 23 Mar 01:00:27.266 * Discarding previously cached master state.
19092:S 23 Mar 01:00:27.441 * MASTER <-> SLAVE sync: receiving 187 bytes from master
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Flushing old data
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Loading DB in memory
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Finished with success
具體流程如下:
- 從服務(wù)器發(fā)送SYNC命令到主服務(wù)器
- 主服務(wù)器通過BGSAVE(子線程中運(yùn)行)生成RDB文件,發(fā)送給從服務(wù)器
- 主服務(wù)器在BGSAVE過程中的寫操作梆掸,保存在緩沖區(qū)中,發(fā)送給從服務(wù)器
進(jìn)行復(fù)制中的主從服務(wù)器雙方的數(shù)據(jù)庫將保存相同的數(shù)據(jù)牙言,概念上將這種現(xiàn)象稱為“數(shù)據(jù)庫狀態(tài)一致”酸钦,或者簡稱“一致”。
舊版復(fù)制功能的缺陷(舊版指的是2.8之前)
在Redis中咱枉,從服務(wù)器對主服務(wù)器的復(fù)制可以分成兩種情況:
- 初次復(fù)制:從服務(wù)器從前沒有復(fù)制過任何主服務(wù)器卑硫,或者從服務(wù)器當(dāng)前要復(fù)制的主服務(wù)器和上一次復(fù)制的主服務(wù)器不同。
- 斷線后重新復(fù)制:處于命令傳播階段的主從服務(wù)器因?yàn)榫W(wǎng)絡(luò)原因而中斷了復(fù)制蚕断,但從服務(wù)器通過自動(dòng)重連接重新連上了主服務(wù)器欢伏,繼續(xù)復(fù)制主服務(wù)器。
對于初次復(fù)制來說來說亿乳,舊版復(fù)制完全沒有問題硝拧,但是斷線重連之后,如果當(dāng)時(shí)從服務(wù)器已經(jīng)復(fù)制了一些葛假,重連之后障陶,從服務(wù)器需要重新復(fù)制,造成一些浪費(fèi)聊训。
舊版使用的是SYNC命令進(jìn)行復(fù)制抱究,是一個(gè)非常浪費(fèi)資源的操作。
新版復(fù)制的優(yōu)勢
使用PSYNC命令替代SYNC命令來執(zhí)行復(fù)制時(shí)的同步操作带斑。
具有完整重同步(full resynchronization)和部分重同步(partial resynchronization)兩種模式:
- 完整重同步:與初次復(fù)制相同鼓寺,都是先讓主服務(wù)器發(fā)送RDB文件,以及向從服務(wù)器發(fā)送保存在緩沖區(qū)里面的命令來進(jìn)行同步勋磕。
- 部分重分步:當(dāng)從服務(wù)器斷線的時(shí)候妈候,下次可以發(fā)起PSYNC命令,從中斷處開始朋凉,執(zhí)行部分重同步州丹,只需要將從服務(wù)器缺少的寫命令發(fā)送給從服務(wù)器執(zhí)行就可以了,這時(shí)使用的資源比起執(zhí)行SYNC命令所需的資源要少的多。
新版復(fù)制實(shí)現(xiàn)
部分重同步功能由以下三個(gè)部分構(gòu)成:
-
主服務(wù)器的復(fù)制偏移量(replication offset)和從服務(wù)器的復(fù)制偏移量
主從服務(wù)器都各自持有一份復(fù)制偏移量墓毒。如果偏移量一致吓揪,表示處于一致狀態(tài);否則所计,兩者處于不一致狀態(tài)柠辞。
-
主服務(wù)器的復(fù)制積壓緩沖區(qū)((replication backlog)
復(fù)制積壓緩沖區(qū)是由主服務(wù)器維護(hù)的一個(gè)固定長度(fixed-size)先進(jìn)先出(FIFO)隊(duì)列,默認(rèn)是1MB主胧。
主服務(wù)器的復(fù)制積壓緩沖區(qū)里面會保存著一部分最近傳播的寫命令叭首,并且復(fù)制積壓緩沖區(qū)會為隊(duì)列中的每個(gè)字節(jié)記錄相應(yīng)的復(fù)制偏移量。
當(dāng)從服務(wù)器重新連上主服務(wù)器時(shí)踪栋,從服務(wù)器會通過PSYNC命令將自己的offset發(fā)送給主服務(wù)器焙格,主服務(wù)器會根據(jù)這個(gè)復(fù)制偏移量來決定對從服務(wù)器執(zhí)行何種同步操作。
-
服務(wù)器的運(yùn)行ID(run ID)
每個(gè)服務(wù)器都有自己的運(yùn)行ID夷都,在服務(wù)器啟動(dòng)時(shí)自動(dòng)生成眷唉,由40個(gè)堆積的十六進(jìn)制字符組成。
當(dāng)從服務(wù)器對主服務(wù)器進(jìn)行初次復(fù)制時(shí)囤官,主服務(wù)器會將自己的運(yùn)行ID傳送給從服務(wù)器冬阳,而從服務(wù)器則會將這個(gè)運(yùn)行ID保存起來。
- 斷線重連后党饮,如果從服務(wù)器保存的運(yùn)行ID與當(dāng)前鏈接的主服務(wù)器的運(yùn)行ID相同肝陪,主服務(wù)器會嘗試執(zhí)行部分重同步操作
- 相反的,如果不一致刑顺,主服務(wù)器將對從服務(wù)器執(zhí)行完整重同步操作氯窍。
PSYNC命令實(shí)現(xiàn)
具體調(diào)用看流程圖即可:
[圖片上傳失敗...(image-5c0f31-1534470142719)]
心跳檢測
在命令傳播階段,從服務(wù)器默認(rèn)會以每秒一次的頻率捏检,向主服務(wù)器發(fā)送命令:
$ REPLCONF ACK <replication_offset>
其中replication_offset是從服務(wù)器當(dāng)前的復(fù)制偏移量荞驴。
發(fā)送REPLCONF ACK有三個(gè)作用:
- 檢測主從服務(wù)器的網(wǎng)絡(luò)連接情況
- 輔助實(shí)現(xiàn)min-slaves選項(xiàng)
- 檢測命令丟失
小結(jié):
- 部分重同步通過復(fù)制偏移量、復(fù)制積壓緩沖區(qū)贯城、服務(wù)器運(yùn)行ID三個(gè)部分來實(shí)現(xiàn)熊楼。
- 在復(fù)制操作剛開始的時(shí)候,從服務(wù)器會成為主服務(wù)器的客戶端能犯,并通過向主服務(wù)器發(fā)送命令請求來執(zhí)行復(fù)制步驟鲫骗,而在復(fù)制操作的后期,主從服務(wù)器互相成為對方的客戶端踩晶。
- 主服務(wù)器通過向從服務(wù)器傳播命令來更新從服務(wù)器的狀態(tài)执泰,保持主從服務(wù)器一致,而從服務(wù)器則通過向主服務(wù)器發(fā)送命令來進(jìn)行心跳檢測渡蜻,以及命令丟失檢測术吝。