您好,登錄后才能下訂單哦!
本文主要介紹Redis replication 主從復(fù)制原理和配置及基本操作 等
主要參考官方文檔:
https://redis.io/topics/replication
http://redisdoc.com/topic/replication.html
一.原理
This system works using three main mechanisms:
系統(tǒng)工作的三個(gè)主要機(jī)制:
1. When a master and a slave instances are well-connected, the master keeps the slave updated by sending a stream of commands to the slave, in order to replicate the effects on the dataset happening in the master side due to: client writes, keys expired or evicted, any other action changing the master dataset.
當(dāng)master和slave實(shí)例連接良好時(shí),master通過(guò)從slave發(fā)送命令流來(lái)更新slave
2. When the link between the master and the slave breaks, for network issues or because a timeout is sensed in the master or the slave, the slave reconnects and attempts to proceed with a partial resynchronization: it means that it will try to just obtain the part of the stream of commands it missed during the disconnection.
當(dāng)master和slave連接中斷時(shí),因?yàn)榫W(wǎng)絡(luò)故障或者感知到master或者slave超時(shí)。Slave重連并試圖進(jìn)行重新同步:意味著獲取失去連接時(shí)丟失的命令流
3. When a partial resynchronization is not possible, the slave will ask for a full resynchronization. This will involve a more complex process in which the master needs to create a snapshot of all its data, send it to the slave, and then continue sending the stream of commands as the dataset changes.
當(dāng)無(wú)法重新部分同步(partial resynchronization)時(shí),slave將要求完全重新同步(full resynchronization)。它將包含一個(gè)復(fù)雜過(guò)程,這過(guò)程中master需要為所有數(shù)據(jù)創(chuàng)建一個(gè)快照,發(fā)送到slave,再繼續(xù)對(duì)變化的數(shù)據(jù)發(fā)送命令流
數(shù)據(jù)安全性概念
Redis的持久化存儲(chǔ)主要提供兩種方式:RDB與AOF
http://redisdoc.com/topic/persistence.html
1. RDB(Snapshot)模式
是默認(rèn)的,即保存某一時(shí)刻的數(shù)據(jù)到硬盤,在下一次觸發(fā)snapshot前如果服務(wù)器crash,在上次snapshot之后修改的數(shù)據(jù)會(huì)丟失。
主要配置redis.conf參數(shù):
save <seconds> <changes>
stop-writes-on-bgsave-error yes
rdbcompression yes
dbfilename dump.rdb
dir ./
參數(shù)說(shuō)明:
save <seconds> <changes>:在X秒內(nèi)如果key有至少X次改變就觸發(fā)持久化,例如save 900 1的話就是在900秒如果key有至少1次改變就觸發(fā)持久化。如果想關(guān)閉此功能的話,可以把全部save行都注釋或刪除或者使用save ""。
stop-writes-on-bgsave-error:在bgsave遇到error的時(shí)候是否停止持久化,默認(rèn)是yes代表是,no代表不是
rdbcompression:是否壓縮,默認(rèn)是yes代表是,no代表不是,如果想節(jié)省CPU的話就設(shè)為no,但rdb文件會(huì)比較大
dbfilename:持久化的文件名字,默認(rèn)是dump.rdb
dir:持久化的目錄名字,默認(rèn)是redis.conf所在的目錄./
2.AOF(append-only file)模式
需要手動(dòng)開(kāi)啟,開(kāi)啟后以追加的方式默認(rèn)每秒鐘將記錄的修改操作保存到硬盤
主要配置redis.conf參數(shù):
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
dir ./
### 以下rewrite參數(shù),AOF模式以追加方式記錄所有寫操作命令到硬盤,文件會(huì)越來(lái)越大,為緩解這種問(wèn)題,redis使用了BGREWRITEAOF用于刪除重復(fù)多余的寫命令,類似BGSAVE,rewrite的時(shí)候會(huì)刪除舊的AOF文件
###
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
參數(shù)說(shuō)明:
appendonly:是否啟動(dòng)aof,默認(rèn)是no代表不啟用
appendfilename:aof的文件名,默認(rèn)是appendonly.aof
appendfsync:觸發(fā)的間隔,默認(rèn)是everysec代表每秒,還可使用always代表有改變都觸發(fā),性能差些但數(shù)據(jù)最安全,no代表讓OS自己決定什么時(shí)候執(zhí)行,性能最好但數(shù)據(jù)不安全
dir:持久化的目錄名字,默認(rèn)是redis.conf所在的目錄./
no-appendfsync-on-rewrite:執(zhí)行rewrite時(shí)appendfsync是否暫停,默認(rèn)no代表不暫停
auto-aof-rewrite-percentage:aof rewrite觸發(fā)時(shí)機(jī),當(dāng)前aof文件大小超過(guò)上一次rewrite后aof文件的百分比后觸發(fā)rewrite。如200,即當(dāng)前的aof文件超過(guò)上一次重寫后aof文件的2倍時(shí)才會(huì)再次rewrite
auto-aof-rewrite-min-size aof文件重寫最小文件大小,即最開(kāi)始aof文件必須要達(dá)到這個(gè)文件時(shí)才觸發(fā),后面的每次重寫就不會(huì)根據(jù)這個(gè)變量了(根據(jù)上一次重寫完成之后的大小).此變量?jī)H初始化啟動(dòng)redis有效.如果是redis恢復(fù)時(shí),則lastSize等于初始aof文件大小.
復(fù)制功能的運(yùn)作原理
無(wú)論是初次連接還是重新連接, 當(dāng)建立一個(gè)從服務(wù)器時(shí), 從服務(wù)器都將向主服務(wù)器發(fā)送一個(gè) SYNC 命令。
接到 SYNC 命令的主服務(wù)器將開(kāi)始執(zhí)行 BGSAVE , 并在保存操作執(zhí)行期間, 將所有新執(zhí)行的寫入命令都保存到一個(gè)緩沖區(qū)里面。
當(dāng) BGSAVE 執(zhí)行完畢后, 主服務(wù)器將執(zhí)行保存操作所得的 .rdb 文件發(fā)送給從服務(wù)器, 從服務(wù)器接收這個(gè) .rdb 文件, 并將文件中的數(shù)據(jù)載入到內(nèi)存中。
之后主服務(wù)器會(huì)以 Redis 命令協(xié)議的格式, 將寫命令緩沖區(qū)中積累的所有內(nèi)容都發(fā)送給從服務(wù)器。
即使有多個(gè)從服務(wù)器同時(shí)向主服務(wù)器發(fā)送 SYNC , 主服務(wù)器也只需執(zhí)行一次 BGSAVE 命令, 就可以處理所有這些從服務(wù)器的同步請(qǐng)求。
從服務(wù)器可以在主從服務(wù)器之間的連接斷開(kāi)時(shí)進(jìn)行自動(dòng)重連, 在 Redis 2.8 版本之前, 斷線之后重連的從服務(wù)器總要執(zhí)行一次完整重同步(full resynchronization)操作, 但是從 Redis 2.8 版本開(kāi)始, 從服務(wù)器可以根據(jù)主服務(wù)器的情況來(lái)選擇執(zhí)行完整重同步還是部分重同步(partial resynchronization)。
部分重同步
從 Redis 2.8 開(kāi)始, 在網(wǎng)絡(luò)連接短暫性失效之后, 主從服務(wù)器可以嘗試?yán)^續(xù)執(zhí)行原有的復(fù)制進(jìn)程(process), 而不一定要執(zhí)行完整重同步操作。
這個(gè)特性需要主服務(wù)器為被發(fā)送的復(fù)制流創(chuàng)建一個(gè)內(nèi)存緩沖區(qū)(in-memory backlog), 并且主服務(wù)器和所有從服務(wù)器之間都記錄一個(gè)復(fù)制偏移量(replication offset)和一個(gè)主服務(wù)器 ID (master run id), 當(dāng)出現(xiàn)網(wǎng)絡(luò)連接斷開(kāi)時(shí), 從服務(wù)器會(huì)重新連接, 并且向主服務(wù)器請(qǐng)求繼續(xù)執(zhí)行原來(lái)的復(fù)制進(jìn)程:
? 如果從服務(wù)器記錄的主服務(wù)器 ID 和當(dāng)前要連接的主服務(wù)器的 ID 相同, 并且從服務(wù)器記錄的偏移量所指定的數(shù)據(jù)仍然保存在主服務(wù)器的復(fù)制流緩沖區(qū)里面, 那么主服務(wù)器會(huì)向從服務(wù)器發(fā)送斷線時(shí)缺失的那部分?jǐn)?shù)據(jù), 然后復(fù)制工作可以繼續(xù)執(zhí)行。
? 否則的話, 從服務(wù)器就要執(zhí)行完整重同步操作。
Redis 2.8 的這個(gè)部分重同步特性會(huì)用到一個(gè)新增的 PSYNC master_run_id offset 內(nèi)部命令, 而 Redis 2.8 以前的舊版本只有 SYNC 命令, 不過(guò), 只要從服務(wù)器是 Redis 2.8 或以上的版本, 它就會(huì)根據(jù)主服務(wù)器的版本來(lái)決定到底是使用 PSYNC master_run_id offset 還是 SYNC :
? 如果主服務(wù)器是 Redis 2.8 或以上版本,那么從服務(wù)器使用 PSYNC master_run_id offset 命令來(lái)進(jìn)行同步。
? 如果主服務(wù)器是 Redis 2.8 之前的版本,那么從服務(wù)器使用 SYNC 命令來(lái)進(jìn)行同步。
二. replication具體配置
實(shí)驗(yàn):一臺(tái)機(jī)器上配置兩個(gè)服務(wù)器 master 6379 slave 6380
版本:redis_version:3.0.6
Master : 除 appendonly改yes,其它 使用默認(rèn)值即可
/usr/local/redis/etc/redis.conf
appendonly yes
因?yàn)樵谕慌_(tái)server上做slave測(cè)試需要復(fù)制一份配置文件,并分別更改端口號(hào),pid文件名字,dump.rdb名字,aof文件名字
Slave
: /usr/local/redis/etc/redis.conf.6380
pidfile /var/run/redis6380.pid
port 6380
dbfilename dump6380.rdb
appendfilename "appendonly6380.aof"
appendonly yes
slaveof 127.0.0.1 6379
注:從 Redis 2.6 開(kāi)始, slave支持只讀模式, 且為slave的默認(rèn)模式。
# Since Redis 2.6 by default slaves are read-only.
slave-read-only yes
開(kāi)啟slave
# redis-server /usr/local/redis/etc/redis.conf.6380
查看狀態(tài)
master中執(zhí)行:
[root@cloud ~]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=57,lag=0
master_repl_offset:57
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:56
127.0.0.1:6379> role
1) "master" --當(dāng)前server角色
2) (integer) 71 --當(dāng)前server復(fù)制偏移量
3) 1) 1) "127.0.0.1" --下屬slave IP
2) "6380" --下屬slave port
3) "71" --下屬slave復(fù)制偏移量
slave中執(zhí)行:
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:83567
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6380> role
1) "slave" --當(dāng)前server角色
2) "127.0.0.1" --上層master IP
3) (integer) 6379 --上層master port
4) "connected"
5) (integer) 83581 --目前從master接收到的復(fù)制副本偏移量
以上,master-slave 配置完成
注:因?yàn)?Redis 使用異步復(fù)制, 所以master發(fā)送的寫數(shù)據(jù)并不一定會(huì)被slave接收到。因此,數(shù)據(jù)丟失可能性仍然是存在的。
為了進(jìn)一步保證數(shù)據(jù)安全,可設(shè)置master服務(wù)器只在有至少 N 個(gè)slave服務(wù)器的情況下,才執(zhí)行寫操作
以下是這個(gè)特性的運(yùn)作原理:
? 從服務(wù)器以每秒一次的頻率 PING 主服務(wù)器一次, 并報(bào)告復(fù)制流的處理情況。
? 主服務(wù)器會(huì)記錄各個(gè)從服務(wù)器最后一次向它發(fā)送 PING 的時(shí)間。
? 用戶可以通過(guò)配置, 指定網(wǎng)絡(luò)延遲的最大值 min-slaves-max-lag
以及執(zhí)行寫操作所需的至少?gòu)姆?wù)器數(shù)量 min-slaves-to-write 。
slave啟用為master
在slave服務(wù)器執(zhí)行命令 SLAVEOF NO ONE 將使得這個(gè)從屬服務(wù)器關(guān)閉復(fù)制功能,并從slave服務(wù)器轉(zhuǎn)變?yōu)閙aster服務(wù)器,原來(lái)同步所得數(shù)據(jù)集不會(huì)被丟棄。
利用“SLAVEOF NO ONE 不會(huì)丟棄同步所得數(shù)據(jù)集”這個(gè)特性,可以在主服務(wù)器失敗的時(shí)候,將從屬服務(wù)器用作新的主服務(wù)器,從而實(shí)現(xiàn)無(wú)間斷運(yùn)行。
上述,介紹了 Redis replication主從復(fù)制原理和最簡(jiǎn)單的配置,后續(xù)會(huì)對(duì)Sentinel,Redis-Cluster等方案做整理
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。