單機部署
redis的單機部署
如何保證redis的高並發和高可用? redis的主從復制原理?redis的哨兵原理?
redis單機能承載多高並發?如果單機扛不住如何擴容扛更多的並發?
redis會不會掛?既然redis會掛如何保證高可用?
Redis主從架構(實現高並發)
單機的redis,能夠承載的QPS大概在上萬到幾萬不等。對於緩存來說,一般是用來支撐讀高並發的,因此架構可以做成一主多從,主節點負責寫,並且將數據復制到其他的從節點,而從節點負責讀,即主從(master-slave)架構。這樣也好實現水平擴容,支撐讀高並發。

- redis采用異常方式復制數據到slave節點,從redis2.8開始,slave node 會周期性確認自己每次復制的數據量
- 一個master node 可以配置多個slave node
- slave node 依然可以鏈接其他slave node
- slave node 復制數據時不會block master node的正常工作
- slave node 復制數據時也不會 block 自己的查詢操作,它會用舊的數據提供服務,但是完成復制后需要刪除舊數據加載新數據,這時會暫停對外服務
- slave node 主要用來進行橫向擴容做讀寫分離,提高讀的吞吐量
另外,主從架構建議開啟master node的持久化,避免master宕機重啟后數據為空,然后一經復制,slave node的數據也丟失了。還有master的備份方案也需要考慮,可以在本地文件丟失后能有備份恢復master,確保master啟動時是正常有數據,即使slave node可以自動接管master node,但也可能sentinel還沒檢測到master failure,master node就自動重啟了,就還會發生復制到slave node數據全部丟失的情形。
主從復制的原理
當啟動一個slave node的時候,它會發送一個PSYNC命令給master node。如果這是slave node初次連接到master node,會觸發一次full resynchronization全量復制,此時master會啟動一個后台線程,開始生成一份RDB快照文件,同時還會將從客戶端新收到的所有寫命令緩存在內存中。RDB文件生成文件后,master會將這個RDB發送給slave,slave會寫入本地磁盤,然后再從本地磁盤加載到內存中,接着master會將內存中緩存的寫命令發送到slave,slave也會同步這些數據。slave node如果跟master node有網絡故障斷開連接會自動重連,此時master node只會復制slave缺少的那部分數據。

主從復制的斷點續傳
從redis2.8開始支持主從復制的斷點續傳,如果主從復制過程中網絡斷開,那么可以接着上次復制的地方繼續復制下去,而不是從頭復制一份。
master node 會在內存中維護一個backlog ,master 和 salve 都會保存一個 replica offset 還有一個master run id ,offset就是保存再backlog中的。如果 master 和 slave 網絡連接斷了,salve 會讓 master 從上次 replica offset 開始繼續復制,如果沒有找到對應的 offset ,那么會執行一次 resynchronization 全量復制。
如果根據 host + ip 定位 master node 是不知道是否復制過的,如果 master node 重啟或者數據發生了變化,那么 slave node 應該根據不同的 run id 區分。
無磁盤化復制
master 再內存中直接創建RDB,然后發送給 salve ,不會再自己本地落地磁盤了,只需要再配置文件中開啟 repl - diskless -sync yes
repl - diskless - sync yes
過期key處理
slave 不會過期 key,只會等待 master 過期 key。 如果 master 過期了一個key,或者通過LRU淘汰了一個key,那么會模擬一條 del 命令發送給slave
復制的流程
slave node 啟動時,會在本地保存master node 的信息,包括 master node 的 host 和 IP ,但是復制流程還沒開始。
slave node 內部有個定時任務,每秒檢查是否有新的 master node 要連接和復制,如果發現,就跟 master node 建立 socket 網絡連接。然后 slave node 發送 ping 命令給 master node 。如果master設置了requirepass,那么slave node 必須發送 masterauth 的口令過去進行認證,master 第一次執行全量復制,后續持續將寫命令異步復制給slave

全量復制
master 執行 bgsave ,在本地生成一份RDB快照文件。
master node 將RDB快照文件發送給salve node ,如果RDB復制時間超過60秒,slave node 會認為復制失敗,當然這個參數可以適當調大
master node 在生成RDB時,會將所有新的命令緩存在內存中,在slave node保存了RDB之后,再將新的命令復制給slave node
如果在復制期間,內存緩沖區持續消耗超過64MB,或者一次性超過256MB,那么停止復制,復制失敗
slave node 接收到RDB之后,清空自己的舊數據,然后重新加載RDB到自己的內存中,同時基於舊的數據版本對外提供服務
如果slave node 開啟了AOF,那么會立即執行BGREWRITEAOF,重寫AOF
增量復制
如果全量復制過程中斷,slave 重新連接 master 時,會觸發增量復制
master 直接從自己的backlog 中獲取部分丟失的數據,發送給slave ,默認backlog是1MB
master 是根據slave 發送的psync 中的offset 來從 backlog 中獲取數據的
異步復制
master 每次接收到寫命令之后,先在內部寫入數據,然后異步發送給salve node
主從節點互相都會發送heartbeat信息,master 默認每隔10秒發送一次heartbeat,slave 每隔一秒發送一個heartbeat
Redis哨兵集群(實現高可用)
如何高可用?
一個salve掛掉是不會影響可用性的,還有很多slave在提供相同數據下的相同讀服務。但是mater掛掉之后,主從就全部失效了。redis的高可用架構,叫做failover故障轉移,也叫主備切換。就是master在故障時,自動檢測,並且將某個slave自動切換為master。這時就可以使用哨兵的機制進行監控、通知、故障轉移、配置更新等操作了。
sentinel 哨兵,用於實現redis集群的高可用,本身也是分布式的,作為一個哨兵集群去運行,互相協同工作。
- 集群監控:監控redis 所有master和slave進程是否正常工作
- 消息通知:如果某個redis實例有故障,那么哨兵負責發送消息作為報警通知給管理員
- 故障轉移:如果master掛掉了,會自動轉移到slave上
- 配置中心:如果故障轉移發送了,通知client客戶端新的master地址
- 故障轉移時,判斷一個master是否宕機,需要大部分的哨兵都同意才行,涉及到了分布式選舉的問題
- 即使部分哨兵也掛了,哨兵集群也是能正常工作的,保證了監控高可用機制的自身也是高可用的。
slave→master(如何選出新的master進行主備切換)
- 判斷slave與master斷開時間的長短,短的優先
- 斷開時間相同的話 根據offset判斷復制數據的多少,復制多的優先
- 復制相同的判斷run id,小的優先
redis實現高並發主要依賴主從架構,同時需要緩存大量數據的話就需要redis集群了,此時再加上哨兵就可以實現任何一個實例宕機都能進行主備切換的高可用。
Redis的一些特性
RDB的優缺點
AOF的優缺點
REDIS的事務:放棄了回滾
一致性哈希算法原理(數據寫入時選擇節點,數據讀取時找到所在節點)
redis 的單線程原子操作的設計
