Sentinel-Redis高可用方案(一):主從複製

引言

大概是由於Redis是我的開發的產品,因此Redis的高可用方案是被分紅了幾塊來實現:主從複製、主從切換以及虛擬IP或客戶端方案。redis

從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.confdom

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端來執行持久化。ui

分別修改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 : 永不過時,返回錯誤spa

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

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以後版本,也多是部分同步操做。orm

部分複製
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. 不然,依然須要全量複製操做;server

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只讀錯誤,不能寫入

相關文章
相關標籤/搜索