寫給大忙人的Redis主從複製,花費五分鐘讓你面試不尷尬

相信不少小夥伴都已經配置過主從複製,可是對於redis主從複製的工做流程和常見問題不少都沒有深刻的瞭解。咔咔此次用時倆天時間給你們整理一份redis主從複製的所有知識點。redis

本文實現所需環境 centos7.0 redis4.0數據庫

@TOCcentos

1、什麼是Redis主從複製?

主從複製就是如今有倆臺redis服務器,把一臺redis的數據同步到另外一臺redis數據庫上。前者稱之爲主節點(master),後者爲從節點(slave)。數據是隻能master往slave同步單向。服務器

可是在實際過程當中是不可能只有倆臺redis服務器來作主從複製的,這也就意味這每臺redis服務器都有可能會稱爲主節點(master)網絡

下圖案例中,咱們的slave3既是master的從節點,也是slave的主節點。併發

先知道這麼個概念,更多詳解繼續查看下文。 負載均衡

在這裏插入圖片描述

2、爲何須要Redis主從複製?

假設咱們如今就一臺redis服務器,也就是單機狀態。socket

在這種狀況下會出現的第一個問題就是服務器宕機,直接致使數據丟失。若是項目是跟¥佔關係的,那形成的後果就可想而知。函數

第二個狀況就是內存問題了,當只有一臺服務器時內存確定會到達峯值的,不可能對一臺服務器進行無限升級的。 學習

在這裏插入圖片描述
因此針對以上倆個問題,咱們就多準備幾臺服務器,配置主從複製。將數據保存在多個服務器上。而且保證每一個服務器的數據是同步的。即便有一個服務器宕機了,也不會影響用戶的使用。redis能夠繼續實現高可用、同時實現數據的冗餘備份。

這會應該會有不少疑問,master跟slave怎麼鏈接呢? 如何同步數據呢? 假如master服務器宕機了呢?彆着急,一點一點解決你的問題。

在這裏插入圖片描述

3、Redis主從複製的做用

在上邊咱們說了爲何使用redis的主從複製,那麼主從複製的做用就是針對爲何使用它來說了。

  1. 咱們繼續使用這個圖來談論
  2. 第一點是數據冗餘了,實現了數據的熱備份,是持久化以外的另外一種方式。
  3. 第二點是針對單機故障問題。當主節點也就是master出現問題時,能夠由從節點來提供服務也就是slave,實現了快速恢復故障,也就是服務冗餘。
  4. 第三點是讀寫分離,master服務器主要是寫,slave主要用來讀數據,能夠提升服務器的負載能力。同時能夠根據需求的變化,添加從節點的數量。
  5. 第四點是負載均衡,配合讀寫分離,有主節點提供寫服務,從節點提供讀服務,分擔服務器負載,尤爲在寫少讀多的狀況下,經過多個從節點分擔讀負載,能夠大大提升redis服務器的併發量和負載。
  6. 第五點是高可用的基石,主從複製是哨兵和集羣可以實施的基礎,所以咱們能夠說主從複製是高可用的基石。

在這裏插入圖片描述

4、配置Redis主從複製

說了這麼多,咱們先簡單的配置一個主從複製案例,而後在談實現的原理。

redis存儲路徑爲:usr/local/redis

日誌跟配置文件存儲在:usr/local/redis/data

首先咱們先配置倆個配置文件,分別爲redis6379.conf 和 redis6380.conf

在這裏插入圖片描述
修改配置文件,主要就是修改端口。爲了查看方便在把日誌文件和持久化文件的名字都用各自的端口來作標識。
在這裏插入圖片描述
而後分別開啓倆個redis服務,一個端口爲6379,一個端口爲6380。執行命令 redis-server redis6380.conf,而後使用 redis-cli -p 6380鏈接,由於redis的默認端口就是6379因此咱們啓動另一臺redis服務器直接使用 redis-server redis6379.conf 而後直接使用 redis-cli直接鏈接就能夠。
在這裏插入圖片描述
這個時候咱們就成功的配置了倆個redis服務,一臺爲6380,一臺爲6379,這裏只是爲了演示。實際工做中是須要配置在倆臺不一樣的服務器的。

在這裏插入圖片描述

1. 使用客戶端命令行啓動

咱們先得有一個概念,就是在配置主從複製時,全部的操做都是在從節點來操做,也就是slave。

那麼咱們在從節點執行一個命令爲 slaveof 127.0.0.1 6379,執行完就表明咱們鏈接上了。

在這裏插入圖片描述
咱們先測試一下看是否實現主從複製。在master這臺服務器上執行倆個 set kaka 123 和 set master 127.0.0.1,而後在slave6380端口是能夠成功獲取到的,也就說明咱們的主從複製就已經配置完成了。可是在實現生產環境可不是就這樣完事了,後邊會在進一步對主從複製進行優化,直到實現高可用。

在這裏插入圖片描述

2. 使用配置文件啓用

在使用配置文件啓動主從複製以前呢!先須要把以前使用客戶端命令行鏈接的斷開,在從主機執行slaveof no one便可斷開主從複製。

在這裏插入圖片描述
在哪能夠查看從節點已經斷開了主節點呢!在主節點的客戶端輸入命令行 info查看

這張圖是使用從節點使用客戶端命令行鏈接主節點後,在主節點的客戶端輸入info打印的信息,能夠看到有一個slave0的一個信息。

在這裏插入圖片描述
這個圖是在從節點執行完 slaveof no one 後,在主節點打印的 info,說明從節點已經跟主節點斷開鏈接了。
在這裏插入圖片描述
在根據配置文件啓動redis服務, redis-server redis6380.conf

當在從節點從新啓動後就能夠在主節點直接查看到從節點的鏈接信息。

在這裏插入圖片描述
測試數據,主節點寫的東西,從節點仍是會自動同步的。
在這裏插入圖片描述

3. 啓動redis服務器時啓動

這種方式配置也是很簡單,在啓動redis服務器時直接就啓動主從複製,執行命令:redis-server --slaveof host port 便可。

4. 主從複製啓動後的日誌信息查看

這個是主節點的日誌信息

在這裏插入圖片描述
這個是從節點的信息,其中有鏈接主節點信息,還有RDB快照保存。
在這裏插入圖片描述

5、主從複製工做原理

1. 主從複製的三個階段

主從複製完整的工做流程分爲如下三個階段。每一段都有本身的內部工做流程,那麼咱們會對這三個過程進行談論。

  • 創建鏈接過程:這個過程就是slave跟master鏈接的過程
  • 數據同步過程:是master給slave同步數據的過程
  • 命令傳播過程:是反覆同步數據
    在這裏插入圖片描述

2. 第一階段:創建鏈接過程

在這裏插入圖片描述
上圖是一個完整主從複製創建鏈接工做流程。而後使用簡短的話語來描述上邊的工做流程。

  1. 設置master的地址和端口,保存master的信息
  2. 創建socket鏈接(這個鏈接作的事情下文會說)
  3. 持續發送ping命令
  4. 身份驗證
  5. 發送slave端口信息

在創建鏈接的過程當中,從節點會保存master的地址和端口、主節點master保存從節點slave的端口。

3. 第二階段:數據同步階段過程

在這裏插入圖片描述
這張圖是詳細描述第一次從節點鏈接主節點時的數據同步過程。

當從節點第一次鏈接主節點時,先會執行一次全量複製此次的全量複製是沒法避免的。

全量複製執行完成後,主節點就會發送複製積壓緩衝區的數據,而後從節點就會執行bgrewriteaof恢復數據,這也就是部分複製。

在這個階段提到了三個新點,全量複製、部分複製、複製緩衝積壓區。會在下文的常見問題裏詳細說明這幾個點。

4. 第三階段:命令傳播階段

當master數據庫被修改後,主從服務器的數據不一致後,此時就會讓主從數據同步到一致,這個過程稱之爲命令傳播。

master會將接收到的數據變動命令發送給slave,slave接收命令後執行命令,讓主從數據達到一致。

命令傳播階段的部分複製

  • 在命令傳播階段出現斷網的狀況,或者網絡抖動時會致使鏈接斷開(connection lost)

  • 這個時候主節點master仍是會繼續往replbackbuffer(複製緩衝積壓區)寫數據

  • 從節點會繼續嘗試鏈接主機(connect to master)

  • 當從節點把本身的runid和複製偏移量發送給主節點,而且執行pysnc命令同步

  • 若是master判斷偏移量是在複製緩衝區範圍內,就會返回continue命令。而且發送複製緩衝區的數據給從節點。

  • 從節點接收數據執行bgrewriteaof,恢復數據

六. 詳細介紹主從複製原理(全量複製+部分複製)

在這裏插入圖片描述
這個過程就是主從複製最齊全的流程講解。那麼下來咱們對每一步進程簡單的介紹

  1. 從節點發送指令psync ? 1 psync runid offset 找對應的runid索取數據。可是這裏能夠考慮一下,當從節點第一次鏈接的時候根本就不知道主節點的runid 和 offset 。因此第一次發送的指令是psync ? 1意思就是主節點的數據我全要。
  2. 主節點開始執行bgsave生成RDB文件,記錄當前的複製偏移量offset
  3. 主節點這個時候會把本身的runid 和 offset 經過 +FULLRESYNC runid offset 指令 經過socket發送RDB文件給從節點。
  4. 從節點接收到+FULLRESYNC 保存主節點的runid和offset 而後清空當前全部數據,經過socket接收RDB文件,開始恢復RDB數據。
  5. 在全量複製後,從節點已經獲取到了主節點的runid和offset,開始發送指令 psync runid offset
  6. 主節點接收指令,判斷runid是否匹配,判斷offset是否在複製緩衝區中。
  7. 主節點判斷runid和offset有一個不知足,就會在返回到步驟2繼續執行全量複製。這裏的runid不匹配只有的多是從節點重啓了這個問題後邊會解決,offset(偏移量)不匹配就是複製積壓緩衝區溢出了。 若是runid或offset校驗經過,從節點的offset和主節點的offset相同時則忽略。 若是runid或offset檢驗經過,從節點的offset與offset不相同,則會發送 +CONTINUE offset(這個offset爲主節點的),經過socket發送複製緩衝區中從節點offset到主節點offset的數據。
  8. 從節點收到+CONTINUE 保存master的offset 經過socket接收到信息後,執行bgrewriteaof,恢復數據。

1-4是全量複製 5-8是部分複製

在主節點的第3步下面 主節點在主從複製的期間是一直在接收客戶端的數據,主節點的offset是一直變化的。只有有變化就會給每一個slave進行發送,這個發送的過程稱之爲心跳機制

七. 心跳機制

在命令傳播階段是,主節點與從節點之間一直都須要進行信息互換,使用心跳機制進行維護,實現主節點和從節點鏈接保持在線。

  • master心跳

    • 指令:ping
    • 默認10秒進行一次,是由參數repl-ping-slave-period決定的
    • 主要作的事情就是判斷從節點是否在線
    • 可使用info replication 來查看從節點租後一次鏈接時間的間隔,lag爲0或者爲1就是正常狀態。
  • slave心跳任務

    • 指令:replconf ack {offset}
    • 每秒執行一次
    • 主要作的事情是給主節點發送本身的複製偏移量,從主節點獲取到最新的數據變動命令,還作一件事情就是判斷主節點是否在線。

心跳階段的注意事項 主節點爲保障數據穩定性,當從節點掛掉的數量或者延遲太高時。將會拒絕全部信息同步。

這裏有倆個參數能夠進行配置調整:

min-slaves-to-write 2

min-slaves-max-lag 8

這倆個參數表示從節點的數量就剩餘2個,或者從節點的延遲大於8秒時,主節點就會強制關閉maste功能,中止數據同步。

那麼主節點是如何知道從節點掛掉的數量和延遲時間呢! 在心跳機制裏邊slave 會每隔一秒發送perlconf ack 這個指令,這個指令可攜帶偏移量,也能夠攜帶從節點的延遲時間和從節點的數量。

8、部分複製的三個核心要素

1. 服務器的運行id (run id)

咱們先看一下這個run id是什麼,執行info命令便可看到。在上文中咱們查看啓動日誌信息也能夠看到。

在這裏插入圖片描述
redis在啓動時會自動生成一個隨機的id(這裏須要注意的是每次啓動的id都會不同),是由40個隨機的十六進制字符串組成,用來惟一識別一個redis節點。

在主從複製初次啓動時,master會把本身的runid發送給slave,slave會保存master的這個id,咱們可使用info命令查看

在這裏插入圖片描述

當斷線重連時,slave把這個id發送給master,若是slave保存的runid與master如今的runid相同,master會嘗試使用部分複製(這塊可否複製成功還有一個因素就是偏移量)。若是slave保存的runid與master如今的runid不一樣,則會直接進行全量複製。

2. 複製積壓緩衝區

複製緩衝積壓區是一個先進先出的隊列,用戶存儲master收集數據的命令記錄。複製緩衝區的默認存儲空間是1M。

能夠在配置文件修改repl-backlog-size 1mb來控制緩衝區大小,這個比例能夠根據本身的服務器內存來修改,咔咔這邊是預留出了30%左右。

複製緩衝區到底存儲的是什麼?

當執行一個命令爲set name kaka時,咱們能夠查看持久化文件查看

在這裏插入圖片描述
那麼複製積壓緩衝區就是存儲的aof持久化的數據,而且以字節分開,而且每一個字節都有本身的偏移量。這個偏移量也就是複製偏移量(offset)
在這裏插入圖片描述
那爲何會說複製緩衝積壓區有可能會致使全量複製呢

在命令傳播階段,主節點會把收集的數據存儲到複製緩衝區中,而後在發送給從節點。就是這裏出現了問題,當主節點數據量在一瞬間特別大的時候,超出了複製緩衝區的內存,就會有一部分數據會被擠出去,從而致使主節點和從節點的數據不一致。從而進行全量複製。若是這個緩衝區大小設置不合理那麼很大可能會形成死循環,從節點就會一直全量複製,清空數據,全量複製。

3. 複製偏移量(offset)

在這裏插入圖片描述
主節點複製偏移量是給從節點發送一次記錄一次,從節點是接收一次記錄一次。

用於同步信息,對比主節點和從節點的差別,當slave斷聯時恢復數據使用。

這個值也就是來本身於複製緩衝積壓區裏邊的那個偏移量。

九. 主從複製常見的問題

1. 主節點重啓問題(內部優化)

當主節點重啓後,runid的值將發生變化,會致使全部的從節點進行全量複製。

這個問題咱們無需考慮,知道系統是怎麼優化的便可。

在創建完主從複製後主節點會建立master-replid變量,這個生成的策略跟runid同樣,長度是41位,runid長度是40位,而後發送給從節點。

在主節點執行shutdown save命令時,進行了一次RDB持久化會把runid 和 offset保存到RDB文件中。可使用命令redis-check-rdb查看該信息。

在這裏插入圖片描述
主節點重啓後加載RDB文件,將文件中的repl-id 和repl-offset加載到內存中。縱使讓全部從節點認爲仍是以前的主節點。

2. 從節點網絡中斷偏移量越界致使全量複製

因爲網絡環境不佳,從節點網絡中斷。複製積壓緩衝區內存太小致使數據溢出,伴隨着從節點偏移量越界,致使全量複製。有可能會致使反覆的全量複製。

解決方案:修改複製積壓緩衝區的大小:repl-backlog-size

設置建議:測試主節點鏈接從節點的時間,獲取主節點每秒平均產生的命令總量write_size_per_second

複製緩衝區空間設置 = 2 * 主從鏈接時間 * 主節點每秒產生的數據總量

3. 頻繁的網路中斷

因爲主節點的cpu佔用太高,或者從節點頻繁鏈接。出現這種狀況形成的結果就是主節點各類資源被嚴重佔用,其中包括但不限於緩衝區,寬帶,鏈接等。

爲何會出現主節點資源被嚴重佔用?

在心跳機制中,從節點每秒會發送一個指令replconf ack指令到主節點。 從節點執行了慢查詢,佔用大量的cpu 主節點每秒調用複製定時函數replicationCron,而後從節點長時間沒有相應。

解決方案:

設置從節點超時釋放

設置參數:repl-timeout

這個參數默認爲60秒。超過60秒,釋放slave。

4. 數據不一致問題

因爲網絡因素,多個從節點的數據會不一致。這個因素是沒有辦法避免的。

關於這個問題給出倆個解決方案:

第一個數據須要高度一致配置一臺redis服務器,讀寫都用一臺服務器,這種方式僅限於少許數據,而且數據需高度一直。

第二個監控主從節點的偏移量,若是從節點的延遲過大,暫時屏蔽客戶端對該從節點的訪問。設置參數爲slave-serve-stale-data yes|no。 這個參數一但設置就只能響應info slaveof等少數命令。

5. 從節點故障

這個問題直接在客戶端維護一個可用節點列表,當從節點故障時,切換到其餘節點進行工做,這個問題在後邊集羣會說到。

十. 總結

本文主要講解了什麼是主從複製、主從複製工做的三大階段以及工做流程、部分複製的三大核心。命令傳播階段的心跳機制。最後說明了主從複製常見問題。

耗時倆天寫的文章,這也是咔咔最近耗時最長的一篇文章,之後咔咔發的文章估計都是這樣的,不會在把一問題單獨出多篇文章來說解,會一篇文章所有說完。不完善知識點或者錯誤知識點,隨着咔咔的知識點增多在回來改善。文章主要是爲了咔咔回顧方便。有什麼問題評論區見。

咔咔但願是你們共同交流學習,不對的能夠指出來,不喜勿噴。

相關文章
相關標籤/搜索