最通俗易懂的 Redis 架構模式詳解

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/0c/0c55f72e8f177872d1452480fbc6c2fd.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  話說有一名意大利程序員,在 2004 年到 2006 年間主要做嵌入式工作,之後接觸了 Web,2007 年和朋友共同創建了一個網站,併爲瞭解決這個網站的負載問題(爲了避免 MySQL 的低性能),於是親自定做一個數據庫,並於 2009 年開發完成,這個就是 Redis。這個意大利程序員就是 Salvatore Sanfilippo 江湖人稱 Redis 之父,大家更習慣稱呼他 Antirez。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8f/8f886e65f705867bdc87d6a5e4180d6d.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis 技術越來越火爆,其超高的性能,簡潔輕量的設計,易上手,分佈式架構的支持,在緩存等領域出色的表現造就了它現在的地位。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  官方的 Benchmark 數據:測試完成了 50 個併發執行 10W 個請求。設置和獲取的值是一個 256 字節字符串。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  結果:讀的速度是 110000次/s,寫的速度是 81000次/s。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  爲了滿足開發市場需求,Redis 支持"},{"type":"text","marks":[{"type":"strong"}],"text":"單機"},{"type":"text","text":"、*"},{"type":"text","marks":[{"type":"italic"}],"text":"主從"},{"type":"text","text":"*、"},{"type":"text","marks":[{"type":"strong"}],"text":"哨兵"},{"type":"text","text":"、*"},{"type":"text","marks":[{"type":"italic"}],"text":"集羣"},{"type":"text","text":"*多種架構模式,本文帶大家詳細講解這幾種架構模式的區別。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"單機模式"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/93/9381dbc537b4c5b5be120e7e0796f278.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  單機模式顧名思義就是安裝一個 Redis,啓動起來,業務調用即可。例如一些簡單的應用,並非必須保證高可用的情況下可以使用該模式。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"優點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"部署簡單;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"成本低,無備用節點;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"高性能,單機不需要同步數據,數據天然一致性。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"缺點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可靠性保證不是很好,單節點有宕機的風險。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單機高性能受限於 CPU 的處理能力,Redis 是單線程的。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  單機 Redis 能夠承載的 QPS(每秒查詢速率)大概在幾萬左右。取決於業務操作的複雜性,Lua 腳本複雜性就極高。假如是簡單的 key value 查詢那性能就會很高。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  假設上千萬、上億用戶同時訪問 Redis,QPS 達到 10 萬+。這些請求過來,單機 Redis 直接就掛了。系統的瓶頸就出現在 Redis 單機問題上,此時我們可以通過"},{"type":"text","marks":[{"type":"strong"}],"text":"主從複製"},{"type":"text","text":"解決該問題,實現系統的高併發。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"主從複製"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/50/50f0fb344f0a4f984332b6a5e7837a17.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis 的複製(Replication)功能允許用戶根據一個 Redis 服務器來創建任意多個該服務器的複製品,其中被複制的服務器爲主服務器(Master),而通過複製創建出來的複製品則爲從服務器(Slave)。 只要主從服務器之間的網絡連接正常,主服務器就會將寫入自己的數據同步更新給從服務器,從而保證主從服務器的數據相同。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  數據的複製是單向的,只能由主節點到從節點,簡單理解就是從節點只支持讀操作,不允許寫操作。主要是讀高併發的場景下用主從架構。主從模式需要考慮的問題是:當 Master 節點宕機,需要選舉產生一個新的 Master 節點,從而保證服務的高可用性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"優點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Master/Slave 角色方便水平擴展,QPS 增加,增加 Slave 即可;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"降低 Master 讀壓力,轉交給 Slave 節點;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主節點宕機,從節點作爲主節點的備份可以隨時頂上繼續提供服務;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"缺點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可靠性保證不是很好,主節點故障便無法提供寫入服務;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒有解決主節點寫的壓力;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據冗餘(爲了高併發、高可用和高性能,一般是允許有冗餘存在的);"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一旦主節點宕機,從節點晉升成主節點,需要修改應用方的主節點地址,還需要命令所有從節點去複製新的主節點,整個過程需要人工干預;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主節點的寫能力受到單機的限制;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主節點的存儲能力受到單機的限制。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"哨兵模式"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9e/9e5d184ba6b817c2f3becae9c565b8fa.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  主從模式中,當主節點宕機之後,從節點是可以作爲主節點頂上來繼續提供服務,但是需要修改應用方的主節點地址,還需要命令所有從節點去複製新的主節點,整個過程需要人工干預。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  於是,在 Redis 2.8 版本開始,引入了哨兵(Sentinel)這個概念,在"},{"type":"text","marks":[{"type":"strong"}],"text":"主從複製的基礎"},{"type":"text","text":"上,哨兵實現了"},{"type":"text","marks":[{"type":"strong"}],"text":"自動化故障恢復"},{"type":"text","text":"。如上圖所示,哨兵模式由兩部分組成,哨兵節點和數據節點:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"哨兵節點:哨兵節點是特殊的 Redis 節點,不存儲數據;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據節點:主節點和從節點都是數據節點。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis Sentinel 是分佈式系統中監控 Redis 主從服務器,並提供主服務器下線時自動故障轉移功能的模式。其中三個特性爲:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"監控(Monitoring):Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"提醒(Notification):當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"自動故障遷移(Automatic failover):當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  接下來我們瞭解一些 Sentinel 中的關鍵名詞,然後系統講解下哨兵模式的工作原理。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"定時任務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Sentinel 內部有 3 個定時任務,分別是:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每 1 秒每個 Sentinel 對其他 Sentinel 和 Redis 節點執行 "},{"type":"codeinline","content":[{"type":"text","text":"PING"}]},{"type":"text","text":" 操作(監控),這是一個"},{"type":"text","marks":[{"type":"strong"}],"text":"心跳檢測"},{"type":"text","text":",是失敗判定的依據。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每 2 秒每個 Sentinel 通過 Master 節點的 channel 交換信息(Publish/Subscribe);"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每 10 秒每個 Sentinel 會對 Master 和 Slave 執行 "},{"type":"codeinline","content":[{"type":"text","text":"INFO"}]},{"type":"text","text":" 命令,這個任務主要達到兩個目的:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\t- 發現 Slave 節點;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\t- 確認主從關係。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"主觀下線"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  所謂主觀下線(Subjectively Down, 簡稱 SDOWN)指的是單個 Sentinel 實例對服務器做出的下線判斷,即單個 Sentinel 認爲某個服務下線(有可能是接收不到訂閱,之間的網絡不通等等原因)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  主觀下線就是說如果服務器在給定的毫秒數之內, 沒有返回 Sentinel 發送的 PING 命令的回覆, 或者返回一個錯誤, 那麼 Sentinel 會將這個服務器標記爲主觀下線(SDOWN)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"客觀下線"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  客觀下線(Objectively Down, 簡稱 ODOWN)指的是多個 Sentinel 實例在對同一個服務器做出 SDOWN 判斷,並且通過命令互相交流之後,得出的服務器下線判斷,然後開啓 failover。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  只有在足夠數量的 Sentinel 都將一個服務器標記爲主觀下線之後, 服務器纔會被標記爲客觀下線(ODOWN)。只有當 Master 被認定爲客觀下線時,纔會發生故障遷移。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"仲裁"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  仲裁指的是配置文件中的 "},{"type":"codeinline","content":[{"type":"text","text":"quorum"}]},{"type":"text","text":" 選項。某個 Sentinel 先將 Master 節點標記爲主觀下線,然後會將這個判定通過 "},{"type":"codeinline","content":[{"type":"text","text":"sentinel is-master-down-by-addr"}]},{"type":"text","text":" 命令詢問其他 Sentinel 節點是否也同樣認爲該 addr 的 Master 節點要做主觀下線。最後當達成這一共識的 Sentinel 個數達到前面說的 "},{"type":"codeinline","content":[{"type":"text","text":"quorum"}]},{"type":"text","text":" 設置的值時,該 Master 節點會被認定爲客觀下線並進行故障轉移。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "},{"type":"codeinline","content":[{"type":"text","text":"quorum"}]},{"type":"text","text":" 的值一般設置爲 Sentinel 個數的"},{"type":"text","marks":[{"type":"strong"}],"text":"二分之一加 1"},{"type":"text","text":",例如 3 個 Sentinel 就設置爲 2。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"哨兵模式工作原理"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"每個 Sentinel 以每秒一次的頻率向它所知的 Master,Slave 以及其他 Sentinel 節點發送一個 "},{"type":"codeinline","content":[{"type":"text","text":"PING"}]},{"type":"text","text":" 命令;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"如果一個實例(instance)距離最後一次有效回覆 PING 命令的時間超過配置文件 "},{"type":"codeinline","content":[{"type":"text","text":"own-after-milliseconds"}]},{"type":"text","text":" 選項所指定的值,則這個實例會被 Sentinel 標記爲"},{"type":"text","marks":[{"type":"strong"}],"text":"主觀下線"},{"type":"text","text":"; "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"如果一個 Master 被標記爲主觀下線,那麼正在監視這個 Master 的所有 Sentinel 要以每秒一次的頻率確認 Master 是否真的進入主觀下線狀態;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"當有"},{"type":"text","marks":[{"type":"strong"}],"text":"足夠數量的 Sentinel"},{"type":"text","text":"(大於等於配置文件指定的值)在"},{"type":"text","marks":[{"type":"strong"}],"text":"指定的時間範圍內確認"},{"type":"text","text":" Master 的確進入了主觀下線狀態,則 Master 會被標記爲"},{"type":"text","marks":[{"type":"strong"}],"text":"客觀下線"},{"type":"text","text":";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"如果 Master 處於 "},{"type":"text","marks":[{"type":"strong"}],"text":"ODOWN 狀態"},{"type":"text","text":",則投票自動選出新的主節點。將剩餘的從節點指向新的主節點繼續進行數據複製;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":6,"align":null,"origin":null},"content":[{"type":"text","text":"在正常情況下,每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有 Master,Slave 發送 "},{"type":"codeinline","content":[{"type":"text","text":"INFO"}]},{"type":"text","text":" 命令;當 Master 被 Sentinel 標記爲客觀下線時,Sentinel 向已下線的 Master 的所有 Slave 發送 INFO 命令的頻率會從 10 秒一次改爲每秒一次; "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":7,"align":null,"origin":null},"content":[{"type":"text","text":"若沒有足夠數量的 Sentinel 同意 Master 已經下線,Master 的客觀下線狀態就會被移除。若 Master 重新向 Sentinel 的 PING 命令返回有效回覆,Master 的主觀下線狀態就會被移除。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" 優點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都有;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主從可以自動切換,系統更健壯,可用性更高;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":" 缺點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主從切換需要時間,會丟失數據;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"還是沒有解決主節點寫的壓力;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"主節點的寫能力,存儲能力受到單機的限制;"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"動態擴容困難複雜,對於集羣,容量達到上限時在線擴容會變得很複雜。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"集羣模式"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  假設上千萬、上億用戶同時訪問 Redis,QPS 達到 10 萬+。這些請求過來,單機 Redis 直接就掛了。系統的瓶頸就出現在 Redis 單機問題上,此時我們可以通過"},{"type":"text","marks":[{"type":"strong"}],"text":"主從複製"},{"type":"text","text":"解決該問題,實現系統的高併發。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  主從模式中,當主節點宕機之後,從節點是可以作爲主節點頂上來繼續提供服務,但是需要修改應用方的主節點地址,還需要命令所有從節點去複製新的主節點,整個過程需要人工干預。於是,在 Redis 2.8 版本開始,引入了"},{"type":"text","marks":[{"type":"strong"}],"text":"哨兵(Sentinel)"},{"type":"text","text":"這個概念,在"},{"type":"text","marks":[{"type":"strong"}],"text":"主從複製的基礎"},{"type":"text","text":"上,哨兵實現了"},{"type":"text","marks":[{"type":"strong"}],"text":"自動化故障恢復"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  哨兵模式中,單個節點的寫能力,存儲能力受到單機的限制,動態擴容困難複雜。於是,Redis 3.0 版本正式推出 "},{"type":"text","marks":[{"type":"strong"}],"text":"Redis Cluster 集羣"},{"type":"text","text":"模式,有效地解決了 Redis 分佈式方面的需求。Redis Cluster 集羣模式具有"},{"type":"text","marks":[{"type":"strong"}],"text":"高可用"},{"type":"text","text":"、*"},{"type":"text","marks":[{"type":"italic"}],"text":"可擴展性"},{"type":"text","text":"*、"},{"type":"text","marks":[{"type":"strong"}],"text":"分佈式"},{"type":"text","text":"、*"},{"type":"text","marks":[{"type":"italic"}],"text":"容錯"},{"type":"text","text":"*等特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/55/55c27768a36bd90b5007d5723db42770.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis Cluster 採用無中心結構,"},{"type":"text","marks":[{"type":"strong"}],"text":"每個節點都可以保存數據"},{"type":"text","text":"和整個集羣狀態,每個節點都和其他所有節點連接。Cluster 一般由多個節點組成,節點數量至少爲 6 個才能保證組成完整高可用的集羣,其中三個爲主節點,三個爲從節點。三個主節點會分配槽,處理客戶端的命令請求,而從節點可用在主節點故障後,頂替主節點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  如上圖所示,該集羣中包含 6 個 Redis 節點,3 主 3 從,分別爲 M1,M2,M3,S1,S2,S3。除了主從 Redis 節點之間進行數據複製外,所有 Redis 節點之間採用 Gossip 協議進行通信,交換維護節點元數據信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  總結下來就是:讀請求分配給 Slave 節點,寫請求分配給 Master,數據同步從 Master 到 Slave 節點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"分片"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  單機、主從、哨兵的模式數據都是存儲在一個節點上,其他節點進行數據的複製。而單個節點存儲是存在上限的,集羣模式就是把數據進行"},{"type":"text","marks":[{"type":"strong"}],"text":"分片"},{"type":"text","text":"存儲,當一個分片數據達到上限的時候,還可以分成多個分片。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis Cluster 採用"},{"type":"text","marks":[{"type":"strong"}],"text":"虛擬哈希槽分區"},{"type":"text","text":",所有的鍵根據哈希函數映射到 0 ~ 16383 整數槽內,計算公式:"},{"type":"codeinline","content":[{"type":"text","text":"HASH_SLOT = CRC16(key) & 16384"}]},{"type":"text","text":"。每一個節點負責維護一部分槽以及槽所映射的鍵值數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/33/33041faac985ee2202969543e8fe694b.png","alt":null,"title":" ","style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis Cluster 提供了靈活的節點擴容和縮容方案。在不影響集羣對外服務的情況下,可以爲集羣添加節點進行擴容也可以下線部分節點進行縮容。可以說,槽是 Redis Cluster 管理數據的基本單位,集羣伸縮就是槽和數據在節點之間的移動。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  簡單的理解就是:擴容或縮容以後,槽需要重新分配,數據也需要重新遷移,但是服務不需要下線。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  假如,這裏有 3 個節點的集羣環境如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 A 哈希槽範圍爲 0 ~ 5500;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 B 哈希槽範圍爲 5501 ~ 11000;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 C 哈希槽範圍爲 11001 ~ 16383。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  此時,我們如果要存儲數據,按照 Redis Cluster 哈希槽的算法,假設結果是: CRC16(key) & 16384 = 6782。 那麼就會把這個key 的存儲分配到 B 節點。此時連接 A、B、C 任何一個節點獲取 key,都會這樣計算,最終通過 B 節點獲取數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  假如這時我們新增一個節點 D,Redis Cluster 會從各個節點中拿取一部分 Slot 到 D 上,比如會變成這樣:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 A 哈希槽範圍爲 1266 ~ 5500;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 B 哈希槽範圍爲 6827 ~ 11000;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 C 哈希槽範圍爲 12288 ~ 16383;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"節點 D 哈希槽範圍爲 0 ~ 1265,5501 ~ 6826,11001 ~ 12287"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  這種特性允許在集羣中輕鬆地添加和刪除節點。同樣的如果我想刪除節點 D,只需要將節點 D 的哈希槽移動到其他節點,當節點是空時,便可完全將它從集羣中移除。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"主從模式"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  Redis Cluster 爲了保證數據的高可用性,加入了主從模式,"},{"type":"text","marks":[{"type":"strong"}],"text":"一個主節點對應一個或多個從節點"},{"type":"text","text":",主節點提供數據存取,從節點複製主節點數據備份,當這個主節點掛掉後,就會通過這個主節點的從節點選取一個來充當主節點,從而保證集羣的高可用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  回到剛纔的例子中,集羣有 A、B、C 三個主節點,如果這 3 個節點都沒有對應的從節點,如果 B 掛掉了,則集羣將無法繼續,因爲我們不再有辦法爲 5501 ~ 11000 範圍內的哈希槽提供服務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  所以我們在創建集羣的時候,一定要爲每個主節點都添加對應的從節點。比如,集羣包含主節點 A、B、C,以及從節點 A1、B1、C1,那麼即使 B 掛掉系統也可以繼續正確工作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  因爲 B1 節點屬於 B 節點的子節點,所以 Redis 集羣將會選擇 B1 節點作爲新的主節點,集羣將會繼續正確地提供服務。當 B 重新開啓後,它就會變成 B1 的從節點。但是請注意,如果節點 B 和 B1 同時掛掉,Redis Cluster 就無法繼續正確地提供服務了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"優點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"無中心架構;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可擴展性,數據按照 Slot 存儲分佈在多個節點,節點間數據共享,節點可動態添加或刪除,可動態調整數據分佈;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"高可用性,部分節點不可用時,集羣仍可用。通過增加 Slave 做備份數據副本。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實現故障自動 failover,節點之間通過 gossip 協議交換狀態信息,用投票機制完成 Slave 到 Master 的角色提升。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"缺點"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據通過異步複製,無法保證"},{"type":"text","marks":[{"type":"strong"}],"text":"數據強一致性"},{"type":"text","text":";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"集羣環境搭建複雜,不過基於 Docker 的搭建方案會相對簡單。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  隨着互聯網的飛速發展,我們享受着技術帶來的便利,同時也給從業者帶來了如何保證項目高併發、低延時的技術挑戰。Redis 以其超高的性能,簡潔輕量的設計,易上手,分佈式架構的支持,在緩存等領域出色的表現等,得到了業界廣泛的關注和應用,在當今高性能架構中,也發揮着越來越重要的作用。甚至可以說,Redis 已經成爲 IT 互聯網大型系統的標配,熟練掌握 Redis 成爲開發、運維人員的必備技能。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  如果不深挖底層,僅僅只是從使用的角度出發,Redis 的學習成本將會非常低。如果作爲一個很好的中間件去研究的話,還是有很多值得學習和借鑑的地方。以上幾種模式,每種都有各自的優缺點,在實際場景中要根據業務特點去選擇合適的模式使用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"   "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"參考資料"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://redis.io/topics/replication"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://redis.io/topics/sentinel"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://redis.io/topics/cluster-tutorial"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://redis.io/topics/cluster-spec"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3f/3f2b7927a66dc6426ff7a6f46f8d35a3.gif","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文采用 "},{"type":"link","attrs":{"href":"http://creativecommons.org/licenses/by-nc-nd/4.0/","title":null},"content":[{"type":"text","text":"知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家可以通過 "},{"type":"link","attrs":{"href":"https://mrhelloworld.com/categories/categories","title":""},"content":[{"type":"text","text":"分類"}]},{"type":"text","text":" 查看更多關於 "},{"type":"link","attrs":{"href":"https://mrhelloworld.com/categories/redis","title":""},"content":[{"type":"text","text":"Redis"}]},{"type":"text","text":" 的文章。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🤗 您的"},{"type":"codeinline","content":[{"type":"text","text":"點贊"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"轉發"}]},{"type":"text","text":"是對我最大的支持。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"📢 掃碼關注 "},{"type":"codeinline","content":[{"type":"text","text":"哈嘍沃德先生"}]},{"type":"text","text":"「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/67/6739b2ed350171f1bca3a0238715c45f.gif","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/eb/eb7b01f031caccf0d514044c9e9f1c66.jpeg","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章