Sentinel-Redis高可用方案(一):主從復制


引言

大概是因為Redis是個人開發的產品,所以Redis的高可用方案是被分成了幾塊來實現:主從復制、主從切換以及虛擬IP或客戶端方案。

從Redis 2.8開始加入對Sentinel機制從而實現了服務器端的主從切換,但目前尚未發現實現虛擬IP或客戶端切換方案。

主從復制研究

wget http://download.redis.io/releases/redis-2.8.2.tar.gz
tar xzf redis-2.8.2.tar.gz

mv redis-2.8.2 /opt/
cp redis.conf redis-master.conf
cp redis.conf redis-slave.conf

cd /opt/redis-2.8.2
make


以下是關於 Redis 復制功能的幾個重要方面:
1. 一個Master可以有多個Slave;
2. Redis使用異步復制。從2.8開始,Slave會周期性(每秒一次)發起一個Ack確認復制流(replication stream)被處理進度;
3. 不僅主服務器可以有從服務器, 從服務器也可以有自己的從服務器, 多個從服務器之間可以構成一個圖狀結構;
4. 復制在Master端是非阻塞模式的,這意味着即便是多個Slave執行首次同步時,Master依然可以提供查詢服務;
5. 復制在Slave端也是非阻塞模式的:如果你在redis.conf做了設置,Slave在執行首次同步的時候仍可以使用舊數據集提供查詢;你也可以配置為當Master與Slave失去聯系時,讓Slave返回客戶端一個錯誤提示;
6. 當Slave要刪掉舊的數據集,並重新加載新版數據時,Slave會阻塞連接請求(一般發生在與Master斷開重連后的恢復階段);
7. 復制功能可以單純地用於數據冗余(data redundancy),也可以通過讓多個從服務器處理只讀命令請求來提升擴展性(scalability): 比如說, 繁重的 SORT 命令可以交給附屬節點去運行。
8. 可以通過修改Master端的redis.config來避免在Master端執行持久化操作(Save),由Slave端來執行持久化。

分別修改redis-master.conf和redis-slave.conf,
daemonize項,改為yes(缺省為no):daemonize yes
maxmemory項,設最大占用內存為50MB:maxmemory 50mb
而有6種內存過期策略,通過maxmemory-policy修改,一般使用默認值或allkeys-lru:
volatile-lru:只對設置了過期時間的key進行LRU(默認值)
allkeys-lru : 是從所有key里 刪除 不經常使用的key
volatile-random:隨機刪除即將過期key
allkeys-random:隨機刪除
volatile-ttl : 刪除即將過期的
noeviction : 永不過期,返回錯誤

修改redis-slave.conf中的端口,避免和Master的相同:port 7379

Redis復制工作原理:
1. 如果設置了一個Slave,無論是第一次連接還是重連到Master,它都會發出一個SYNC命令;
2. 當Master收到SYNC命令之后,會做兩件事:
a) Master執行BGSAVE,即在后台保存數據到磁盤(rdb快照文件);
b) Master同時將新收到的寫入和修改數據集的命令存入緩沖區(非查詢類);
3. 當Master在后台把數據保存到快照文件完成之后,Master會把這個快照文件傳送給Slave,而Slave則把內存清空后,加載該文件到內存中;
4. 而Master也會把此前收集到緩沖區中的命令,通過Reids命令協議形式轉發給Slave,Slave執行這些命令,實現和Master的同步;
5. Master/Slave此后會不斷通過異步方式進行命令的同步,達到最終數據的同步一致;
6. 需要注意的是Master和Slave之間一旦發生重連都會引發全量同步操作。但在2.8之后版本,也可能是部分同步操作。

部分復制
2.8開始,當Master和Slave之間的連接斷開之后,他們之間可以采用持續復制處理方式代替采用全量同步。
Master端為復制流維護一個內存緩沖區(in-memory backlog),記錄最近發送的復制流命令;同時,Master和Slave之間都維護一個復制偏移量(replication offset)和當前Master服務器ID(Master run id)。當網絡斷開,Slave嘗試重連時:
a. 如果MasterID相同(即仍是斷網前的Master服務器),並且從斷開時到當前時刻的歷史命令依然在Master的內存緩沖區中存在,則Master會將缺失的這段時間的所有命令發送給Slave執行,然后復制工作就可以繼續執行了;
b. 否則,依然需要全量復制操作;

Redis 2.8 的這個部分重同步特性會用到一個新增的 PSYNC 內部命令, 而 Redis 2.8 以前的舊版本只有 SYNC 命令, 不過, 只要從服務器是 Redis 2.8 或以上的版本, 它就會根據主服務器的版本來決定到底是使用 PSYNC 還是 SYNC :

如果主服務器是 Redis 2.8 或以上版本,那么從服務器使用 PSYNC 命令來進行同步。
如果主服務器是 Redis 2.8 之前的版本,那么從服務器使用 SYNC 命令來進行同步。

配置Slave
只需要將redis-slave.conf中REPLICATION段中的slaveof <masterip> <masterport>行的注釋去掉,並修改為:
slaveof 127.0.0.1 6379
即完成該Slave的配置,並指向本地端口為6379的Master端。

masterauth
如果Master端通過requirepass設置了密碼,Slave需要對應的通過masterauth <password>設置密碼;

slave-serve-stale-data
當Slave和Master斷開連接時,Slave是直接返回錯誤提示還是利用歷史數據響應客戶端(或是直接返回空數據,當全量復制進行時)。yes是缺省值,即利用歷史數據響應。


slave-read-only
缺省模式下,Slave服務器是只讀的。

repl-ping-slave-peroid
即心跳檢測間隔時間,缺省值為10秒。

repl-timeout 60
復制超時

啟動Redis
#redis-server redis-master.conf
#redis-server redis-slave.conf
使用ps查看進程
#ps -ef | grep redis
還可以用netstat查看端口
#netstat -tpln

驗證主從復制
#redis-cli set test 1000
#redis-cli get test #只能說明目前Master工作正常,不能說明Slave已經復制數據
根據剛剛查看到的端口號,把端口號是6379的Master進程殺掉
#kill -9 XXXX(PID號)
#redis-cli -p 7379 get test #連接到Slave上,讀取test
#redis-cli -p 7379 set test 1000 #會提示Slave只讀錯誤,不能寫入


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM