您好,登錄后才能下訂單哦!
Redis主從復制原理是什么?這個問題可能是我們日常學習或工作經常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家帶來的參考內容,讓我們一起來看看吧!
主從復制就是現在有倆臺redis服務器,把一臺redis的數據同步到另一臺redis數據庫上。前者稱之為主節點(master),后者為從節點(slave)。數據是只能master往slave同步單向。
但是在實際過程中是不可能只有倆臺redis服務器來做主從復制的,這也就意味這每臺redis服務器都有可能會稱為主節點(master)
下圖案例中,我們的slave3既是master的從節點,也是slave的主節點。
先知道這么個概念,更多詳解繼續查看下文。
假設我們現在就一臺redis服務器,也就是單機狀態。
在這種情況下會出現的第一個問題就是服務器宕機,直接導致數據丟失。如果項目是跟¥占關系的,那造成的后果就可想而知。
第二個情況就是內存問題了,當只有一臺服務器時內存肯定會到達峰值的,不可能對一臺服務器進行無限升級的。所以針對以上倆個問題,我們就多準備幾臺服務器,配置主從復制。將數據保存在多個服務器上。并且保證每個服務器的數據是同步的。即使有一個服務器宕機了,也不會影響用戶的使用。redis可以繼續實現高可用、同時實現數據的冗余備份。
這會應該會有很多疑問,master跟slave怎么連接呢? 如何同步數據呢? 假如master服務器宕機了呢?別著急,一點一點解決你的問題。
在上邊我們說了為什么使用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,這里只是為了演示。實際工作中是需要配置在倆臺不同的服務器的。
我們先得有一個概念,就是在配置主從復制時,所有的操作都是在從節點來操作,也就是slave。
那么我們在從節點執行一個命令為 slaveof 127.0.0.1 6379
,執行完就代表我們連接上了。我們先測試一下看是否實現主從復制。在master這臺服務器上執行倆個set kaka 123 和 set master 127.0.0.1
,然后在slave6380端口是可以成功獲取到的,也就說明我們的主從復制就已經配置完成了。但是在實現生產環境可不是就這樣完事了,后邊會在進一步對主從復制進行優化,直到實現高可用。
在使用配置文件啟動主從復制之前呢!先需要把之前使用客戶端命令行連接的斷開,在從主機執行slaveof no one
即可斷開主從復制。在哪可以查看從節點已經斷開了主節點呢!在主節點的客戶端輸入命令行info
查看
這張圖是使用從節點使用客戶端命令行連接主節點后,在主節點的客戶端輸入info
打印的信息,可以看到有一個slave0的一個信息。這個圖是在從節點執行完slaveof no one
后,在主節點打印的info
,說明從節點已經跟主節點斷開連接了。在根據配置文件啟動redis服務,redis-server redis6380.conf
當在從節點重新啟動后就可以在主節點直接查看到從節點的連接信息。測試數據,主節點寫的東西,從節點還是會自動同步的。
這種方式配置也是很簡單,在啟動redis服務器時直接就啟動主從復制,執行命令:redis-server --slaveof host port
即可。
這個是主節點的日志信息這個是從節點的信息,其中有連接主節點信息,還有RDB快照保存。
主從復制完整的工作流程分為以下三個階段。每一段都有自己的內部工作流程,那么我們會對這三個過程進行談論。
上圖是一個完整主從復制建立連接工作流程。然后使用簡短的話語來描述上邊的工作流程。
在建立連接的過程中,從節點會保存master的地址和端口、主節點master保存從節點slave的端口。
這張圖是詳細描述第一次從節點連接主節點時的數據同步過程。
當從節點第一次連接主節點時,先會執行一次全量復制這次的全量復制是無法避免的。
全量復制執行完成后,主節點就會發送復制積壓緩沖區的數據,然后從節點就會執行bgrewriteaof恢復數據,這也就是部分復制。
在這個階段提到了三個新點,全量復制、部分復制、復制緩沖積壓區。會在下文的常見問題里詳細說明這幾個點。
當master數據庫被修改后,主從服務器的數據不一致后,此時就會讓主從數據同步到一致,這個過程稱之為命令傳播。
master會將接收到的數據變更命令發送給slave,slave接收命令后執行命令,讓主從數據達到一致。
「命令傳播階段的部分復制」
在命令傳播階段出現斷網的情況,或者網絡抖動時會導致連接斷開(connection lost)
這個時候主節點master還是會繼續往replbackbuffer(復制緩沖積壓區)寫數據
從節點會繼續嘗試連接主機(connect to master)
當從節點把自己的runid和復制偏移量發送給主節點,并且執行pysnc命令同步
如果master判斷偏移量是在復制緩沖區范圍內,就會返回continue命令。并且發送復制緩沖區的數據給從節點。
從節點接收數據執行bgrewriteaof,恢復數據
這個過程就是主從復制最齊全的流程講解。那么下來我們對每一步進程簡單的介紹
psync ? 1 psync runid offset
找對應的runid
索取數據。但是這里可以考慮一下,當從節點第一次連接的時候根本就不知道主節點的runid 和 offset
。所以第一次發送的指令是psync ? 1
意思就是主節點的數據我全要。psync runid offset
2
繼續執行全量復制。這里的runid不匹配只有的可能是從節點重啟了這個問題后邊會解決,offset(偏移量)不匹配就是復制積壓緩沖區溢出了。 如果runid或offset校驗通過,從節點的offset和主節點的offset相同時則忽略。 如果runid或offset檢驗通過,從節點的offset與offset不相同,則會發送 +CONTINUE offset(這個offset為主節點的),通過socket發送復制緩沖區中從節點offset到主節點offset的數據。「1-4是全量復制 5-8是部分復制」
在主節點的第3步下面 主節點在主從復制的期間是一直在接收客戶端的數據,主節點的offset是一直變化的。只有有變化就會給每個slave進行發送,這個發送的過程稱之為心跳機制
在命令傳播階段是,主節點與從節點之間一直都需要進行信息互換,使用心跳機制進行維護,實現主節點和從節點連接保持在線。
master心跳
slave心跳任務
「心跳階段的注意事項」主節點為保障數據穩定性,當從節點掛掉的數量或者延遲過高時。將會拒絕所有信息同步。
這里有倆個參數可以進行配置調整:
min-slaves-to-write 2
min-slaves-max-lag 8
這倆個參數表示從節點的數量就剩余2個,或者從節點的延遲大于8秒時,主節點就會強制關閉maste功能,停止數據同步。
那么主節點是如何知道從節點掛掉的數量和延遲時間呢! 在心跳機制里邊slave 會每隔一秒發送perlconf ack 這個指令,這個指令可攜帶偏移量,也可以攜帶從節點的延遲時間和從節點的數量。
我們先看一下這個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不同,則會直接進行全量復制。
復制緩沖積壓區是一個先進先出的隊列,用戶存儲master收集數據的命令記錄。復制緩沖區的默認存儲空間是1M。
可以在配置文件修改repl-backlog-size 1mb
來控制緩沖區大小,這個比例可以根據自己的服務器內存來修改,咔咔這邊是預留出了30%左右。
「復制緩沖區到底存儲的是什么?」
當執行一個命令為set name kaka
時,我們可以查看持久化文件查看那么復制積壓緩沖區就是存儲的aof持久化的數據,并且以字節分開,并且每個字節都有自己的偏移量。這個偏移量也就是復制偏移量(offset)「那為什么會說復制緩沖積壓區有可能會導致全量復制呢」
在命令傳播階段,主節點會把收集的數據存儲到復制緩沖區中,然后在發送給從節點。就是這里出現了問題,當主節點數據量在一瞬間特別大的時候,超出了復制緩沖區的內存,就會有一部分數據會被擠出去,從而導致主節點和從節點的數據不一致。從而進行全量復制。如果這個緩沖區大小設置不合理那么很大可能會造成死循環,從節點就會一直全量復制,清空數據,全量復制。
主節點復制偏移量是給從節點發送一次記錄一次,從節點是接收一次記錄一次。
用于同步信息,對比主節點和從節點的差異,當slave斷聯時恢復數據使用。
這個值也就是來自己于復制緩沖積壓區里邊的那個偏移量。
當主節點重啟后,runid的值將發生變化,會導致所有的從節點進行全量復制。
這個問題我們無需考慮,知道系統是怎么優化的即可。
在建立完主從復制后主節點會創建master-replid變量,這個生成的策略跟runid一樣,長度是41位,runid長度是40位,然后發送給從節點。
在主節點執行shutdown save命令時,進行了一次RDB持久化會把runid 和 offset保存到RDB文件中。可以使用命令redis-check-rdb查看該信息。
主節點重啟后加載RDB文件,將文件中的repl-id 和repl-offset加載到內存中。縱使讓所有從節點認為還是之前的主節點。
由于網絡環境不佳,從節點網絡中斷。復制積壓緩沖區內存過小導致數據溢出,伴隨著從節點偏移量越界,導致全量復制。有可能會導致反復的全量復制。
解決方案:修改復制積壓緩沖區的大小:repl-backlog-size
設置建議:測試主節點連接從節點的時間,獲取主節點每秒平均產生的命令總量write_size_per_second
復制緩沖區空間設置 = 2 * 主從連接時間 * 主節點每秒產生的數據總量
由于主節點的cpu占用過高,或者從節點頻繁連接。出現這種情況造成的結果就是主節點各種資源被嚴重占用,其中包括但不限于緩沖區,寬帶,連接等。
為什么會出現主節點資源被嚴重占用?
在心跳機制中,從節點每秒會發送一個指令replconf ack指令到主節點。 從節點執行了慢查詢,占用大量的cpu 主節點每秒調用復制定時函數replicationCron,然后從節點長時間沒有相應。
解決方案:
設置從節點超時釋放
設置參數:repl-timeout
這個參數默認為60秒。超過60秒,釋放slave。
由于網絡因素,多個從節點的數據會不一致。這個因素是沒有辦法避免的。
關于這個問題給出倆個解決方案:
第一個數據需要高度一致配置一臺redis服務器,讀寫都用一臺服務器,這種方式僅限于少量數據,并且數據需高度一直。
第二個監控主從節點的偏移量,如果從節點的延遲過大,暫時屏蔽客戶端對該從節點的訪問。設置參數為slave-serve-stale-data yes|no。 這個參數一但設置就只能響應info slaveof等少數命令。
感謝各位的閱讀!看完上述內容,你們對Redis主從復制原理是什么大概了解了嗎?希望文章內容對大家有所幫助。如果想了解更多相關文章內容,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。