redis重启命令_这可能是你见过最全面的Redis主从复制原理
在Redis復制的基礎上(不包括Redis Cluster或Redis Sentinel作為附加層提供的高可用功能),使用和配置主從復制非常簡單,能使得從 Redis 服務器(下文稱 slave)能精確得復制主 Redis 服務器(下文稱 master)的內容。每次當 slave 和 master 之間的連接斷開時, slave 會自動重連到 master 上,并且無論這期間 master 發生了什么, slave 都將嘗試讓自身成為 master 的精確副本。
該系統的運行依靠三個重要機制: 1. 當一個 master 實例和一個 slave 實例連接正常時, master 會發送一連串命令流保持對 slave 的更新,以便將自身數據集的改變復制給 slave,這包括客戶端的寫入、key 的過期或被逐出等等 2. 當 master 和 slave 斷連后,因為網絡問題、或者是主從意識到連接超時, slave 重新連接上 master 并會嘗試進行部分重同步:這意味著它會嘗試只獲取在斷開連接期間內丟失的命令流 3. 當無法進行部分重新同步時, slave 會請求全量重同步。這涉及到一個更復雜過程,比如master 需要創建所有數據的快照,將之發送給 slave ,之后在數據集更改時持續發送命令流到 slave
Redis使用默認的異步復制,低延遲且高性能,適用于大多數 Redis 場景。但是,slave會異步確認其從master周期接收到的數據量。
客戶端可使用 WAIT 命令來請求同步復制某些特定的數據。但是,WAIT 命令只能確保在其他 Redis 實例中有指定數量的已確認的副本:在故障轉移期間,由于不同原因的故障轉移或是由于 Redis 持久性的實際配置,故障轉移期間確認的寫入操作可能仍然會丟失。
Redis 復制特點
- Redis 使用異步復制,slave 和 master 之間異步地確認處理的數據量
- 一個 master 可以擁有多個 slave
- slave 可以接受其他 slave 的連接。除了多個 slave 可以連接到同一 master , slave 之間也可以像層級連接其它 slave。Redis 4.0 起,所有的 sub-slave 將會從 master 收到完全一樣的復制流
- Redis 復制在 master 側是非阻塞的,即master 在一或多 slave 進行初次同步或者是部分重同步時,可以繼續處理查詢請求
- 復制在 slave 側大部分也是非阻塞的。當 slave 進行初次同步時,它可以使用舊數據集處理查詢請求,假設在 redis.conf 中配置了讓 Redis 這樣做的話。否則,你可以配置如果復制流斷開, Redis slave 會返回一個 error 給客戶端。但是,在初次同步之后,舊數據集必須被刪除,同時加載新的數據集。 slave 在這個短暫的時間窗口內(如果數據集很大,會持續較長時間),會阻塞到來的連接請求。自 Redis 4.0 開始,可以配置 Redis 使刪除舊數據集的操作在另一個不同的線程中進行,但是,加載新數據集的操作依然需要在主線程中進行并且會阻塞 slave
- 復制可被用在可伸縮性,以便只讀查詢可以有多個 slave 進行(例如 O(N) 復雜度的慢操作可以被下放到 slave ),或者僅用于數據安全和高可用
- 可使用復制來避免 master 將全部數據集寫入磁盤造成的開銷:一種典型的技術是配置你的 master 的 redis.conf以避免對磁盤進行持久化,然后連接一個 slave ,配置為不定期保存或是啟用 AOF。但是,這個設置必須小心處理,因為重啟的 master 將從一個空數據集開始:如果一個 slave 試圖與它同步,那么這個 slave 也會被清空!
1 單機“危機”
- 容量瓶頸
- 機器故障
- QPS瓶頸
- 一主多從
主從復制作用
- 數據副本
- 擴展讀性能
總結
2 實現復制的操作
如下兩種實現方式:
slaveof 命令
- 異步執行,很耗時間
無需重啟,但是不便于配置的管理。
配置
slaveof ip port slave-read-only yes雖然可統一配置,但是需要重啟。
3 全量復制
RDB生成、RDB通過網絡拷貝、slave舊數據的清理、slave aof rewrite,很耗費時間
如果復制的數據量在4G~6G之間,那么很可能全量復制時間消耗到1分半到2分鐘
3.1 全量復制開銷
3.2 全量同步細節
master 開啟一個后臺save進程,以便生成一個 RDB 文件。同時它開始緩沖所有從客戶端接收到的新的寫入命令。當后臺save完成RDB文件時, master 將該RDB數據集文件發給 slave, slave會先將其寫入磁盤,然后再從磁盤加載到內存。再然后 master 會發送所有緩存的寫命令發給 slave。這個過程以指令流的形式完成并且和 Redis 協議本身的格式相同。
當主從之間的連接因為一些原因崩潰之后, slave 能夠自動重連。如果 master 收到了多個 slave 要求同步的請求,它會執行一個單獨的后臺保存,以便于為多個 slave 服務。
4 增量復制
5 master關閉持久化時的復制安全性
在使用 Redis 復制功能時的設置中,推薦在 master 和 slave 中啟用持久化。 當不可能啟用時,例如由于非常慢的磁盤性能而導致的延遲問題,應該配置實例來避免重啟后自動重新開始復制。
關閉持久化并配置了自動重啟的 master 是危險的: 1. 設置節點 A 為 master 并關閉它的持久化設置,節點 B 和 C 從 節點 A 復制數據 2. 節點 A 宕機,但它有一些自動重啟系統可重啟進程。但由于持久化被關閉了,節點重啟后其數據集是空的! 3. 這時B、C 會從A復制數據,但A數據集空,因此復制結果是它們會銷毀自身之前的數據副本!
當 Redis Sentinel 被用于高可用并且 master 關閉持久化,這時如果允許自動重啟進程也是很危險的。例如, master 可以重啟的足夠快以致于 Sentinel 沒有探測到故障,因此上述的故障模式也會發生。 任何時候數據安全性都是很重要的,所以如果 master 使用復制功能的同時未配置持久化,那么自動重啟進程這項就該被禁用。
6 復制工作原理
- 每個 master 都有一個 replication ID :一個較大的偽隨機字符串,標記了一個給定的數據集。
每個 master 也持有一個偏移量,master 將自己產生的復制流發送給 slave 時,發送多少個字節的數據,自身的偏移量就會增加多少,目的是當有新的操作修改自己的數據集時,它可據此更新 slave 的狀態。
復制偏移量即使在沒有一個 slave 連接到 master 時,也會自增,所以基本上每一對給定的 Replication ID, offset 都會標識一個 master 數據集的確切版本。
psync
slave使用psync從master復制,psync runid offset
master會根據自身情況返回響應信息: - 可能是FULLRESYNC runid offset觸發全量復制 - 可能是CONTINUE觸發增量復制
slave 連接到 master 時,它們使用 PSYNC 命令來發送它們記錄的舊的 master replication ID 和它們至今為止處理的偏移量。通過這種方式, master 能夠僅發送 slave 所需的增量部分。 但若 master 的緩沖區中沒有足夠的命令積壓緩沖記錄,或者如果 slave 引用了不再知道的歷史記錄(replication ID),則會轉而進行一個全量重同步:在這種情況下, slave 會得到一個完整的數據集副本,從頭開始。即: - 若slave重連master,那么master僅會復制給slave缺少的部分數據 - 若第一次連接master,那么會觸發全量復制
7 復制的完整流程
slave如果跟master有網絡故障,斷開連接會自動重連。 master如果發現有多個slave都重新連接,僅會啟動一個rdb save操作,用一份數據服務所有slave。heartbeat
主從節點互相都會發送heartbeat信息。 master默認每隔10秒發送一次heartbeat,salve node每隔1秒發送一個heartbeat。
8 斷點續傳
Redis 2.8開始支持主從復制的斷點續傳
主從復制過程,若網絡連接中斷,那么可以接著上次復制的地方,繼續復制下去,而不是從頭開始復制一份。
master和slave都會維護一個offset
- master在自身基礎上累加offset,slave亦是
- slave每秒都會上報自己的offset給master,同時master保存每個slave的offset
master和slave都要知道各自數據的offset,才能知曉互相之間的數據不一致情況。
backlog
master會在內存中維護一個backlog,默認1MB。master給slave復制數據時,也會將數據在backlog中同步寫一份。
backlog主要是用做全量復制中斷時候的增量復制。
master和slave都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。若master和slave網絡連接中斷,slave會讓master從上次replica offset開始繼續復制。但若沒有找到對應offset,就會執行resynchronization。
master run id
- info server,可見master run id
根據host+ip定位master node,是不靠譜的,如果master node重啟或者數據出現了變化,那么slave node應該根據不同的run id區分,run id不同就做全量復制。 如果需要不更改run id重啟redis,可使用:
redis-cli debug reload9 無磁盤化復制
master在內存中直接創建RDB,然后發送給slave,不會在自己本地持久化。 只需要在配置文件中開啟repl-diskless-sync yes即可.
等待 5s 再開始復制,因為要等更多 slave 重連 repl-diskless-sync-delay 510 處理過期key
Redis 的過期機制可以限制 key 的生存時間。此功能取決于 Redis 實例計算時間的能力,但是,即使使用 Lua 腳本更改了這些 key,Redis slaves 也能正確地復制具有過期時間的 key。
為實現這功能,Redis 不能依靠主從使用同步時鐘,因為這是一個無法解決的問題并且會導致 race condition 和數據不一致,所以 Redis 使用三種主要的技術使過期的 key 的復制能夠正確工作: 1. slave 不會讓 key 過期,而是等待 master 讓 key 過期。當一個 master 讓一個 key 到期(或由于 LRU 算法刪除)時,它會合成一個 DEL 命令并傳輸到所有 slave 2. 但由于這是 master 驅動的 key 過期行為,master 無法及時提供 DEL 命令,所以有時 slave 的內存中仍然可能存在邏輯上已過期的 key 。為了處理這問題,slave 使用它的邏輯時鐘以報告只有在不違反數據集的一致性的讀取操作(從主機的新命令到達)中才存在 key。用這種方法,slave 避免報告邏輯過期的 key 仍然存在。在實際應用中,使用 slave 程序進行縮放的 HTML 碎片緩存,將避免返回已經比期望的時間更早的數據項 3. 在Lua腳本執行期間,不執行任何 key 過期操作。當一個Lua腳本運行時,從概念上講,master 中的時間是被凍結的,這樣腳本運行的時候,一個給定的鍵要么存在要么不存在。這可以防止 key 在腳本中間過期,保證將相同的腳本發送到 slave ,從而在二者的數據集中產生相同的效果。
一旦 slave 被提升 master ,它將開始獨立過期 key,而不需要任何舊 master 幫助。
11 重新啟動和故障轉移后的部分重同步
Redis 4.0 開始,當一個實例在故障轉移后被提升為 master 時,它仍然能夠與舊 master 的 slave 進行部分重同步。為此,slave 會記住舊 master 的舊 replication ID 和復制偏移量,因此即使詢問舊的 replication ID,也可以將部分復制緩沖提供給連接的 slave 。
但是,升級的 slave 的新 replication ID 將不同,因為它構成了數據集的不同歷史記錄。例如,master 可以返回可用,并且可以在一段時間內繼續接受寫入命令,因此在被提升的 slave 中使用相同的 replication ID 將違反一對復制標識和偏移對只能標識單一數據集的規則。
另外,slave 在關機并重新啟動后,能夠在 RDB 文件中存儲所需信息,以便與 master 進行重同步。這在升級的情況下很有用。當需要時,最好使用 SHUTDOWN 命令來執行 slave 的保存和退出操作。
參考
- https://raw.githubusercontent.com/antirez/redis/2.8/00-RELEASENOTES
- https://redis.io/topics/replication
http://weixin.qq.com/r/2Sm5oWTESTk2rSDC93zL (二維碼自動識別)
總結
以上是生活随笔為你收集整理的redis重启命令_这可能是你见过最全面的Redis主从复制原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 重装系统后电脑没声声音怎么办 电脑重装后
- 下一篇: 土耳其离中国有多远