關於redis中的Replication

來源:互聯網
上載者:User

關於redis中的Replication

一、簡介

Redis的replication機制允許slave從master那裡通過網路傳輸拷貝到完整的資料備份。具有以下特點:

  • 非同步複製
  • 可以配置一主多從
  • 可以配置從伺服器可以級聯從伺服器,既 M->S->S
  • M replication時是非阻塞的(在replication期間,M依然能夠處理用戶端的請求)
  • S replication期間也是非阻塞的(也可以接受來自用戶端的請求,但是它用的是之前的舊資料)可以通過配置來決定S是否在進行replication時用舊資料響應用戶端的請求,如果配置為否,那麼slave將會返回一個錯誤訊息給用戶端。不過當新的資料接收完全後,必須將新資料與舊資料替換,即刪除舊資料,在替換資料的這個時間視窗內,slave將會拒絕用戶端的請求和串連
  • 能夠通過replication來避免master每次持久化時都將整個資料集持久化到硬碟中。只需把master配置為不進行save操作,然後串連上一個slave,這個slave則被配置為不時地進行save操作的。不過需要注意的是,在這個用例中,必須確保master不會自動啟動

二、Master持久化功能關閉時Replication的安全性

當有需要使用到replication機制時,一般都會強烈建議把master的持久化開關開啟。即使為了避免持久化帶來的延遲影響,不把持久化開關開啟,那麼也應該把master配置為不會自動啟動的

為了更好地理解當一個不進行持久化的master如果允許自動啟動所帶來的危險性。可以看看下面這種失敗情形:

假設我們有一個redis節點A,設定為master,並且關閉持久化功能,另外兩個節點B和C是它的slave,並從A複製資料。

  • 如果A節點崩潰了導致所有的資料都丟失了,它會有重啟系統來重啟進程。但是由於持久化功能被關閉了,所以即使它重啟了,它的資料集是空的。而B和C依然會通過replication機制從A複製資料,所以B和C會從A那裡複製到一份空的資料集,並用這份空的資料集將自己本身的非空的資料集替換掉。於是就相當於丟失了所有的資料
  • 即使使用一些HA工具,比如說sentinel來監控master-slaves叢集,也會發生上述的情形,因為master可能崩潰後迅速恢複。速度太快而導致sentinel無法察覺到一個failure的發生
  • 資料的安全很重要、持久化開關被關閉並且有replication發生的時候,應該禁止執行個體的自啟動

三、M/S replication的工作原理

  • 當master和slave啟動時,不管這個slave是否是第一次串連上Master,它都會發送一個SYNC命令給master提取複寫資料
  • master收到SYNC命令後,會在後台進行資料持久化,持久化期間,master會繼續接收用戶端的請求,它會把這些可能修改資料集的請求緩衝在記憶體中。當持久化進行完畢以後,master會把這份資料集發送給slave,slave會把接收到的資料進行持久化,然後再載入到記憶體中。然後,master再將之前緩衝在記憶體中的命令發送給slave
  • 當master與slave之間的串連由於某些原因而斷開時,slave能夠自動重連Master,如果master收到了多個slave並發串連請求,它只會進行一次持久化,然後再把這一份持久化的資料發送給多個並發串連的slave
  • 當master和slave斷開重連後,一般都會對整份資料進行複製。但從redis2.8版本開始,支援部分複製

資料部分複製

從2.8版本開始,slave與master能夠在網路連接斷開重連後只進行部分資料複製。

master會在其記憶體中建立一個複製流的等待隊列,master和它所有的slave都維護了複製的資料下標和master的進程id,因此,當網路連接斷開後,slave會請求master繼續進行未完成的複製,從所記錄的資料下標開始。如果進程id變化了,或者資料下標不可用,那麼將會進行一次全部資料的複製。支援部分資料複製的命令是PSYNC

不需硬碟參與的Replication

一般情況下,一次複製需要將記憶體的資料寫到硬碟中,再將資料從硬碟讀進記憶體,再發送給slave。對於速度比較慢的硬碟,這個操作會給master帶來效能上的損失。Redis2.8版本開始,實驗性地加上了無硬碟複製的功能。這個功能能將資料從記憶體中直接發送到slave,而不用經過硬碟的儲存。不過這個功能目前處於實驗階段,還未正式發布

四、配置M/S

 slaveof <masterip> <masterport>

slave執行個體需要配置該項,指向master的(ip, port)

masterauth <master-password>

如果master執行個體啟用了密碼保護,則該配置項需填master的啟動密碼;若master未啟用密碼,該配置項需要注釋掉

slave-serve-stale-data

指定slave與master串連中斷時的動作。預設為yes,表明slave會繼續應答來自client的請求,但這些資料可能已經到期(因為串連中斷導致無法從master同步)

若配置為no,則slave除正常應答"INFO"和"SLAVEOF"命令外,其餘來自用戶端的請求命令均會得到"SYNC with master in progress"的應答,

直到該slave與master的串連重建成功或該slave被提升為master。

 

slave-read-only

指定slave是否唯讀,預設為yes。若配置為no,這表示slave是可寫的,但寫的內容在主從同步完成後會被刪掉

repl-ping-slave-period

Redis部署為Replication模式後,slave會以預定周期(預設10s)發PING包給master,該配置可以更改這個預設周期

repl-timeout

有2種情況的逾時均由該配置指定:1) Bulk transfer I/O timeout; 2) master data or ping response timeout

需要特別注意的是:若修改預設值,則使用者輸入的值必須大於repl-ping-slave-period的配置值,否則在主從鏈路延時較高時,會頻繁timeout

repl-disable-tcp-nodelay

指定向slave同步資料時,是否禁用socket的NO_DELAY選項。

若配置為yes,則禁用NO_DELAY,則TCP協議棧會合并小包統一發送,這樣可以減少主從節點間的包數量並節省頻寬,但會增加資料同步到slave的時間

若配置為no,表明啟用NO_DELAY,則TCP協議棧不會延遲小包的發送時機,這樣資料同步的延時會減少,但需要更大的頻寬

通常情況下,應該配置為no以降低同步延時,但在主從節點間網路負載已經很高的情況下,可以配置為yes

備忘:socket的NO_DELAY選項涉及到TCP協議棧的擁塞控制演算法—Nagle's Algorithm

slave-priority

指定slave的優先順序。在不只1個slave存在的部署環境下,當master宕機時,Redis Sentinel會將priority值最小的slave提升為master

需要注意的是,若該配置項為0,則對應的slave永遠不會被Redis Sentinel自動提升為master


replication相關的配置比較簡單,只需要把下面一行加到slave的設定檔中

slaveof 192.168.1.1 6379

你也可以通過用戶端發送SLAVEOF命令給slave。無硬碟複製功能可以通過repl-diskless-sync來配置,另外一個配置項repl-diskless-sync-delay用來配置當收到第一個請求時,等待多個slave一起來請求之間的間隔時間

1、同時啟動兩個Redis伺服器,可以考慮在同一台機器上啟動兩個Redis伺服器,分別監聽不同的連接埠,如6379和6380

2、設定檔為6379.conf 6380.conf

3、啟動並配置

./src/redis-server  6380.conf

./src/redis-server  6379.conf 

4、測試

[root@localhost redis]# ./src/redis-cli  -p 6379

127.0.0.1:6379> flushdb

OK

127.0.0.1:6379> set aa 1

OK

127.0.0.1:6379> set bb 2

OK

127.0.0.1:6379> set cc 3

OK

127.0.0.1:6379> exit

[root@localhost redis]# ./src/redis-cli  -p 6380

127.0.0.1:6380> keys *

1) "bb"

2) "aa"

3) "cc"

127.0.0.1:6380> get aa

"1"

127.0.0.1:6380> get bb

"2"

五、only read slave

從redis2.6版本開始,slave支援唯讀模式,而且是預設的。可以通過配置項slave-read-only來進行配置,並且支援用戶端使用CONFIG SET命令來動態修改配置

唯讀slave會拒絕所有的寫請求,唯讀slave並不是為了防範不可信的用戶端,畢竟一些管理命令例如DEBUG和CONFIG在唯讀模式下還是可以使用的。如果確實要確保安全性,那麼可以在設定檔中將一些命令重新命名。也許你會感到很奇怪,為什麼能夠將一個唯讀模式的slave恢複為可寫的呢,儘管可寫,但是只要slave一同步master的資料,就會丟失那些寫在slave的資料。不過還是有一些合法的應用情境需要儲存瞬時資料會用到這個特性。不過,之後可能會考慮廢除掉這個特性。Setting a slave to authenticate to a master

如果master通過requirepass配置項設定了密碼,slave每次同步操作都需要驗證密碼,可以通過在slave的設定檔中添加以下配置項:

masterauth <password>

也可以通過用戶端在運行時發送以下命令:

config set masterauth <password>

六、至少N個slave才允許向master寫資料

從redis2.8版本開始,master可以被配置為只有當master當前有至少N個slave串連著的時候才接受寫資料的請求;由於redis是非同步複製的,所以它並不能保證slave會收到一個寫請求,所以總有一個資料丟失的時間視窗存在

這個機制的工作原理如下所示:

  • slave每秒發送ping心跳給master,詢問當前複製了多少資料
  • master會記錄下它上次收到某個slave的ping心跳是什麼時候
  • 使用者可以配置一個時間,來指定ping心跳的發送不應超過的一個逾時時間

如果master有至少N個slave,並且ping心跳的逾時不超過M秒,那麼它就會接收寫請求。也許你會認為這情形好似CAP理論中弱化版的C(consistency),因為寫請求並不能保證資料的一致性,但這樣做,至少資料丟失被限制在了限定的時間內,即M秒

如果N和M的條件都無法達到,那麼master會回複一個錯誤資訊。寫請求也不會被處理

有兩個配置項用來配置上文中提到的N和M:

min-slaves-to-write <number of slaves>

min-slaves-max-lag <number of seconds>

下面關於Redis的文章您也可能喜歡,不妨參考下:

Ubuntu 14.04下Redis安裝及簡單測試

Redis主從複製基本配置

Redis叢集明細文檔

Ubuntu 12.10下安裝Redis(圖文詳解)+ Jedis串連Redis

Redis系列-安裝部署維護篇

CentOS 6.3安裝Redis

Redis安裝部署學習筆記

Redis設定檔redis.conf 詳解

Redis 的詳細介紹:請點這裡
Redis 的:請點這裡

本文永久更新連結地址:

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.