Redis主從複製下的工做原理梳理

Redis主從複製的配置十分簡單,它可使從服務器是主服務器的徹底拷貝。須要清除Redis主從複製的幾點重要內容:redis

1數據庫

2緩存

3安全

4服務器

5網絡

6less

7異步

8優化

9spa

10

11

1)Redis使用異步複製。但從Redis 2.8開始,從服務器會週期性的應答從複製流中處理的數據量。

2)一個主服務器能夠有多個從服務器。

3)從服務器也能夠接受其餘從服務器的鏈接。除了多個從服務器鏈接到一個主服務器以外,多個從服務器也能夠鏈接到一個從服務器上,造成一個

   圖狀結構。

4)Redis主從複製不阻塞主服務器端。也就是說當若干個從服務器在進行初始同步時,主服務器仍然能夠處理請求。

5)主從複製也不阻塞從服務器端。當從服務器進行初始同步時,它使用舊版本的數據來應對查詢請求,假設你在redis.conf配置文件是這麼配置的。

   不然的話,你能夠配置當複製流關閉時讓從服務器給客戶端返回一個錯誤。可是,當初始同步完成後,須要刪除舊的數據集和加載新的數據集,在

   這個短暫的時間內,從服務器會阻塞鏈接進來的請求。

6)主從複製能夠用來加強擴展性,使用多個從服務器來處理只讀的請求(好比,繁重的排序操做能夠放到從服務器去作),也能夠簡單的用來作數據冗餘。

7)使用主從複製能夠爲主服務器免除把數據寫入磁盤的消耗:在主服務器的redis.conf文件中配置「避免保存」(註釋掉全部「保存「命令),而後鏈接一個配

   置爲「進行保存」的從服務器便可。可是這個配置要確保主服務器不會自動重啓(要得到更多信息請閱讀下一段)

當主服務器不進行持久化時複製的安全性

1

2

3

4

5

6

7

8

9

10

11

12

在進行主從複製設置時,強烈建議在主服務器上開啓持久化,當不能這麼作時,好比考慮到延遲的問題,應該將實例配置爲避免自動重啓。

 

爲何不持久化的主服務器自動重啓很是危險呢?

爲了更好的理解這個問題,看下面這個失敗的例子,其中主服務器和從服務器中數據庫都被刪除了。

 

設置節點A爲主服務器,關閉持久化,節點B和C從節點A複製數據。

這時出現了一個崩潰,但Redis具備自動重啓系統,重啓了進程,由於關閉了持久化,節點重啓後只有一個空的數據集。

節點B和C從節點A進行復制,如今節點A是空的,因此節點B和C上的複製數據也會被刪除。

當在高可用系統中使用Redis Sentinel,關閉了主服務器的持久化,而且容許自動重啓,這種狀況是很危險的。

好比主服務器可能在很短的時間就完成了重啓,以致於Sentinel都沒法檢測到此次失敗,那麼上面說的這種失敗的狀況就發生了。

 

若是數據比較重要,而且在使用主從複製時關閉了主服務器持久化功能的場景中,都應該禁止實例自動重啓。

Redis主從複製是如何工做的

1

2

3

4

5

6

7

8

9

10

11

12

若是設置了一個從服務器,在鏈接時它發送了一個SYNC命令,無論它是第一次鏈接仍是再次鏈接都沒有關係。

 

而後主服務器開始後臺存儲,而且開始緩存新鏈接進來的修改數據的命令。當後臺存儲完成後,主服務器把數據文件發送到從服務器,

從服務器將其保存在磁盤上,而後加載到內存中。而後主服務器把剛纔緩存的命令發送到從服務器。這是做爲命令流來完成的,而且

和Redis協議自己格式相同。

 

你能夠經過telnet本身嘗試一下。在Redis服務器工做時鏈接到Redis端口,發送SYNC命令,會看到一個批量的傳輸,而且主服務器接收

的每個命令都會經過telnet會話從新發送一遍。

 

當主從服務器之間的鏈接因爲某些緣由斷開時,從服務器能夠自動進行重鏈接。當有多個從服務器同時請求同步時,主服務器只進行一個後臺存儲。

 

當鏈接斷開又從新連上以後,通常都會進行一個完整的從新同步,可是從Redis2.8開始,只從新同步一部分也能夠。

部分從新同步

1

2

3

4

5

6

7

8

9

10

從Redis 2.8開始,若是遭遇鏈接斷開,從新鏈接以後能夠從中斷處繼續進行復制,而沒必要從新同步。

 

它的工做原理是這樣:

主服務器端爲複製流維護一個內存緩衝區(in-memory backlog)。主從服務器都維護一個複製偏移量(replication offset)和master run id 

當鏈接斷開時,從服務器會從新鏈接上主服務器,而後請求繼續複製,假如主從服務器的兩個master run id相同,而且指定的偏移量在內存緩衝

區中還有效,複製就會從上次中斷的點開始繼續。若是其中一個條件不知足,就會進行徹底從新同步(在2.8版本以前就是直接進行徹底從新同步)。

由於主運行id不保存在磁盤中,若是從服務器重啓了的話就只能進行徹底同步了。

 

部分從新同步這個新特性內部使用PSYNC命令,舊的實現中使用SYNC命令。Redis2.8版本能夠檢測出它所鏈接的服務器是否支持PSYNC命令,不支持的

話使用SYNC命令。

無磁盤複製

1

2

3

4

一般來說,一個徹底從新同步須要在磁盤上建立一個RDB文件,而後加載這個文件以便爲從服務器發送數據。

 

若是使用比較低速的磁盤,這種操做會給主服務器帶來較大的壓力。Redis從2.8.18版本開始嘗試支持無磁盤的複製。

使用這種設置時,子進程直接將RDB經過網絡發送給從服務器,不使用磁盤做爲中間存儲。

配置

1

2

3

4

5

6

7

8

9

10

主從複製的配置十分簡單:把下面這行加入到從服務器的配置文件中便可。

slaveof 192.168.1.1 6379

 

固然你須要把其中的192.168.1.1 6379替換爲你本身的主服務器IP(或者主機名hostname)和端口。另外你能夠調用SLAVEOF命令,

主服務器就會開始與從服務器同步。

 

關於部分從新同步,還有一些針對複製內存緩衝區的優化參數。查看Redis介質中的Redis.conf示例得到更多信息。

 

使用repl-diskless-sync配置參數來啓動無磁盤複製。使用repl-diskless-sync-delay 參數來配置傳輸開始的延遲時間,以便等待

更多的從服務器鏈接上來。查看Redis介質中的Redis.conf示例得到更多信息。

只讀從服務器

1

2

3

4

5

6

7

8

從Redis 2.6開始,從服務器支持只讀模式,而且是默認模式。這個行爲是由Redis.conf文件中的slave-read-only 參數控制的,

能夠在運行中經過CONFIG SET來啓用或者禁用。

 

只讀的從服務器會拒絕全部寫命令,因此對從服務器不會有誤寫操做。但這不表示能夠把從服務器實例暴露在危險的網絡環境下,

由於像DEBUG或者CONFIG這樣的管理命令仍是能夠運行的。不過你能夠經過使用rename-command命令來爲這些命令更名來增長安全性。

 

你可能想知道爲何只讀限制還能夠被還原,使得從服務器還能夠進行寫操做。雖然當主從服務器進行從新同步或者從服務器重啓後,

這些寫操做都會失效,仍是有一些使用場景會想從服務器中寫入臨時數據的,但未來這個特性可能會被去掉。

限制有N個以上從服務器才容許寫入

1

2

3

4

5

6

7

8

9

10

11

12

13

14

從Redis 2.8版本開始,能夠配置主服務器鏈接N個以上從服務器才容許對主服務器進行寫操做。可是,由於Redis使用的是異步主從複製,

沒辦法確保從服務器確實收到了要寫入的數據,因此仍是有必定的數據丟失的可能性。

 

這一特性的工做原理以下:

1)從服務器每秒鐘ping一次主服務器,確認處理的複製流數量。

2)主服務器記住每一個從服務器最近一次ping的時間。

3)用戶能夠配置最少要有N個服務器有小於M秒的確認延遲。

4)若是有N個以上從服務器,而且確認延遲小於M秒,主服務器接受寫操做。

 

還能夠把這看作是CAP原則(一致性,可用性,分區容錯性)不嚴格的一致性實現,雖然不能百分百確保一致性,但至少保證了丟失的數據不會超過M秒內的數據量。

 

若是條件不知足,主服務器會拒絕寫操做並返回一個錯誤。

1)min-slaves-to-write(最小從服務器數)

2)min-slaves-max-lag(從服務器最大確認延遲)

相關文章
相關標籤/搜索