(四)redis高可用保障
A. 持久化
- RDB模式持久化
- 簡述:該模式即為快照的概念,直接將redis內存的數(shù)據(jù)拷貝到本地磁盤,一般設置拷貝的執(zhí)行間隔會較久,如一天一次或者一小時一次。
- 實現(xiàn)機制:具體實現(xiàn)基于save & bgsave兩種方式。
- save:較不常用,易導致redis長時間處于阻塞狀態(tài)。
- bgsave:RDB模式下默認的持久化方式,會fork子進程進行持久化以保障redis的阻塞僅在fork動作的瞬間發(fā)生。
- 觸發(fā)事件
- 周期性觸發(fā):redis.conf配置文件中會設置
save m n,該配置默認使用bgsave命令,表示在m秒內發(fā)生n次修改時觸發(fā)持久化。master & slave都會基于此配置周期性的進行bgsave,生成相應的rdb文件。 - 主從建立:建立主從關系時slave會執(zhí)行全量復制(sync),此時master自動觸發(fā)bgsave生成rdb文件并發(fā)送給slave。
- 重啟:shutdown后重啟,若沒有開啟aof時會自動執(zhí)行bgsave。
- debug:debug reload時,會導致save的操作。
- 周期性觸發(fā):redis.conf配置文件中會設置
- 優(yōu)點
- 具體某個時間點的快照,且便于復制到其他redis server上進行數(shù)據(jù)恢復。
- 恢復數(shù)據(jù)的速度遠快于aof。
- 缺點
- 實時性較差,若對于災后數(shù)據(jù)丟失的容忍性較低,則不建議使用。
- rdb格式的版本較多,存在版本互相不兼容的潛在風險。
- AOF模式持久化
- 簡述:該模式會獨立創(chuàng)建日志以記錄redis的所有歷史命令,重啟后會根據(jù)記錄重新執(zhí)行所有命令來恢復所有數(shù)據(jù)。
- 觸發(fā)事件:僅在redis重啟時且redis.conf配置了
appendonly yes&appendfilename xxx.aof會觸發(fā)該模式。 - 運行順序
- redis命令會append到aof buffer然后再寫入日志,在buffer寫入日志文件時,建議配置
everysec兼顧性能和數(shù)據(jù)安全; - aof日志文件會越變越大,因此定期會對其重寫實現(xiàn)壓縮,亦可使用
bgrewriteaof手動觸發(fā)壓縮; - redis重啟后使用aof日志文件開始恢復數(shù)據(jù)。
- redis命令會append到aof buffer然后再寫入日志,在buffer寫入日志文件時,建議配置
- 優(yōu)點:高時效性,保障數(shù)據(jù)的完整性。
- 缺點:redis時cpu密集型服務,而aof會fork子進程來進行持久化將占用較大內存,當前以copy on write來進行父子進程間內存共享來緩解該問題。
B. 主從機制 & 同步問題
- 簡述
- 為保障redis的高可用性生產(chǎn)中幾乎不會使用單點redis,至少是最簡單主從模式,多會采用哨兵模式或者集群模式。
- master & slave間的數(shù)據(jù)同步,默認使用
repl-disable-tcp-nodelay no,即開啟tcp-nodelay來降低同步延遲,不會等待合并包以確保高時效性。若設置成repl-disable-tcp-nodelay yes則默認情況下會增加時延40ms,節(jié)約帶寬消耗。
1. 數(shù)據(jù)同步
概述:redis2.8及以上版本,使用
psync完成主從數(shù)據(jù)同步,同步過程分為全量復制 & 部分復制兩類。-
psync:具體命令為于slave上使用
psync runID offset。- 若master響應fullresync,則觸發(fā)全量復制。
- 若master響應continue,則進行部分復制。
- 注意,低版本下使用該命令,基于僅支持sync命令所以會響應error。
全量復制:一般僅在初次建立主從關系時會使用該模式,master通過bgsave將全量rdb數(shù)據(jù)同步至slave,網(wǎng)絡開銷較大。
-
部分復制:多用于主從復制時網(wǎng)絡閃斷等造成的數(shù)據(jù)丟失場景。若slave再次成功連接master,情況允許下master會補發(fā)丟失數(shù)據(jù)給slave,相對全部重發(fā)而言降低了網(wǎng)絡開銷。為支撐該功能,psync的部分復制過程需要下面三個組件
復制偏移量:slave每秒都會上報自己的offset給master,該數(shù)值可參考
info replication中顯示的offset內容。復制積壓緩沖區(qū):master有了對應slave時創(chuàng)建的對象,是保存在master上的固定長度的隊列(queue, FIFO),默認大小為1mb,其核心功能保存最近已復制數(shù)據(jù)的功能,用于psync時丟失的數(shù)據(jù)補救。因為master響應set命令時,把該命令發(fā)送給slave的同時也會將之寫入復制積壓緩沖區(qū)。
-
主節(jié)點運行ID(runID):redis啟動后會動態(tài)分配一個40bits的十六進制string作為runID用于識別redis節(jié)點。
- slave保存master的runID,便于slave識別自己從誰那兒復制。
- runID可用
info server進行查看確認。master重啟后runID會變化,slave無法部分增量復制,只可全量復制。 - 不可僅靠復制偏移量offset來進行部分復制,因為重啟后master可能會加載其他的rdb文件導致數(shù)據(jù)變化。
退化問題:若復制積壓緩沖區(qū)失效(slave請求的offset不在隊列存儲的offset內),runID即便未變化,也無法完成部分復制,只能進行全量復制。
-
心跳:master & slave建立長連接后會發(fā)送心跳以維持,雙方彼此都有心跳檢測機制。
master:默認master每10s對slave進行ping命令,具體周期可通過
repl-ping-slave-period的參數(shù)進行控制。slave:在主線程中每隔1s發(fā)送replconf ack上報自己offset,告知master自己的復制偏移量。
判定:master根據(jù)replconf命令判定slave的超時時間,可在
info replication的lag字段確認,正常應該在1-2之間。默認配置repl-timeout為60s,若slave發(fā)送給master的時間超過60s,則判定slave下線。
異步復制:master不僅負責數(shù)據(jù)讀寫,還需把寫命令set 同步給slave。master發(fā)送寫命令是異步的,自身處理完寫命令并回復client,無需等待slave回復復制是否完成。
-
過期數(shù)據(jù)同步:master存儲了大量設置超時的數(shù)據(jù)時需注意同步問題,數(shù)據(jù)的刪除設計兩種策略。
惰性刪除:該策略下slave不會主動刪除,master處理讀取命令時檢查key過期與否,若過期執(zhí)行del刪除并把該命令同步給slave讓其也刪除對應key。
定時刪除:master會定時采樣一定量的key,若發(fā)現(xiàn)采樣中有key過期則執(zhí)行del,再同步給salve同步刪除。若此時大量數(shù)據(jù)超時,master采樣速度跟不上過期速度且master沒讀到過期的key,那么slave就收不到del命令,這會導致從slave上讀取到過期數(shù)據(jù)。升級redis3.2后,讀取slave時會再檢查key過期與否再決定是否返回給client數(shù)據(jù)。
2. 簡單主從模式
實現(xiàn)方式:slave節(jié)點的redis.conf加入
slaveof master-ip master-port,或者連接客戶端使用slaveof xxx命令。-
復制過程:在slave上配置相關信息后啟動時,或者使用
slaveof xxx命令時已經(jīng)激活復制的流程。- slave會保存master的信息,可通過
info replication查詢保存的具體信息內容; - slave定時(每秒)維護復制邏輯,依靠這個定時任務發(fā)現(xiàn)master的存在并與之建立連接;
- 建立主從連接時具體建立一個socket專門接收master發(fā)出的復制命令,打印日志
connecting to master xxxx:6379; - 若建立連接失敗,定時任務會持續(xù)嘗試,可手動
slaveof no one結束這個嘗試的循環(huán); - 建立主從成功后,slave發(fā)送ping命令請求通信,以此檢測主從間的socket是否可用,并確認master是否可接受處理命令;
- 若master有設置
requirepass參數(shù),則需要進行權限驗證,確保slave的masterauth參數(shù)與之相同; - 上方步驟全部完成后,開始同步數(shù)據(jù)。對于首次建立復制的場景master本身完成一次basave,將所有數(shù)據(jù)都傳給slave。這一步操作是最耗時的;
- 后續(xù)master會持續(xù)將寫命令發(fā)送給slave,保證主從一致性。
- slave會保存master的信息,可通過
-
配置文件redis.conf參考
bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout 60 tcp-keepalive 300 daemonize yes supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "/apprun/redis/logs/redis.log" databases 16 always-show-logo yes save 86400 1 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /apprun/data/redis masterauth Admin!123 replica-serve-stale-data yes replica-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no repl-backlog-size 100mb replica-priority 100 requirepass xx123 maxmemory 5gb # 在redis達到maxmemory閾值時,采用lru算法將設置過期時間的key刪除。使用該策略后,內存共享池機制失效。 maxmemory-policy volatile-lru lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes aof-use-rdb-preamble yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 stream-node-max-bytes 4096 stream-node-max-entries 100 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 0 0 0 client-output-buffer-limit pubsub 32mb 8mb 60 # 內存回收策略:定時任務刪除expired key,hz 10即每秒運行10次檢測一次。 hz 10 dynamic-hz yes aof-rewrite-incremental-fsync yes rdb-save-incremental-fsync yes slave-serve-stale-data yes slave-read-only yes slaveof 10.xx.10.xx 6379
3. 哨兵模式sentinel
-
概述:簡單的主從模式,若master節(jié)點down后,slave切換master需要通過
slaveof no one手動實現(xiàn),且調用redis的模塊需要修改ip地址并進行重啟?;诖朔N場景,redis sentinel分布式架構應運而生。- 補充說明:簡單的主從模式基于vip+keepalived的模式亦可實現(xiàn)自動切換主從且不用修改應用模塊的配置文件,但不如哨兵模式簡單直接。
-
架構 & 工作流程
- 包含若干sentinel節(jié)點和redis數(shù)據(jù)節(jié)點。
- 若sentinel節(jié)點發(fā)現(xiàn)節(jié)點不可達時,會對該節(jié)點做下線標識。
- 若被標識的是master節(jié)點,sentinel會和其他sentinel節(jié)點投票協(xié)商。
- 若大多數(shù)sentinel認為master不可達,則它們會選舉一個sentinel節(jié)點完成自動故障轉移工作,同時通知redis應用方。
-
故障轉移步驟細節(jié)
- master故障,兩個slave節(jié)點和master失去連接(默認結構為1主2從的redis數(shù)據(jù)節(jié)點,3個sentinel節(jié)點),主從復制中斷。
- sentinel節(jié)點監(jiān)控發(fā)現(xiàn)master出現(xiàn)故障。
- 多個sentinel節(jié)點投票一致確認故障情況,選舉出sentinel-3為leader負責故障轉移。
- sentinel-3自動選擇slave-1通過
slaveof no one升級為master,并讓slave-2更新自己的master對象,再通知客戶端當前的master情況,最后讓舊master恢復后也對應更新主從關系。
-
sentinel節(jié)點核心功能
- 監(jiān)控:定期檢測redis數(shù)據(jù)節(jié)點、其余sentinel節(jié)點是否可達。
- 通知:將故障轉移結果通知給應用方。
- 主節(jié)點故障轉移:實現(xiàn)slave升級master,并維護主從關系。
- 配置提供方:客戶端初始化連接的是sentinel節(jié)點集合,從中獲取master信息。
-
實現(xiàn)方式
sentinel需要投票完成選主,所以server數(shù)量為奇數(shù)(一般3即可,一主兩從,三個sentinel監(jiān)控);
完成/apprun/redis/etc/下redis.conf的配置內容(默認6379端口),注意配置slaveof xx;
-
進行/apprun/redis/conf/下sentinel.conf配置;
# 3份sentinel配置文件,監(jiān)控的都是當時作為master節(jié)點的redis ip+port,即所有sentinel的配置文件內容其實是一樣的 & 投票需要的決定數(shù)目 # 使用端口 port 26379 # 工作目錄 dir "/apprun/redis" daemonize yes # 日志所在路徑 logfile "/apprun/redis/logs/sentinel.log" sentinel deny-scripts-reconfig yes # sentinel monitor <master-name-custemized> <ip> <port> <quorum>,quorum用于判定主節(jié)點不可達時需要的票數(shù)。 sentinel monitor mymaster 172.xx.xx.3x 6379 2 # sentinel down-after-milliseconds <master-name-custemized> <times>,每個sentinel定期ping master,若5000ms未回復,即判定離線。 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 18000 sentinel auth-pass mymaster xxpassxxxword 最后使用
./redis-sentinel sentinel.conf啟動,并檢查logs文件確認啟動成功與否。
-
原理解釋
- 三個定時任務
- 每10s,sentinel節(jié)點會向master和slave發(fā)送
info reolication命令獲取整體拓撲結構。 - 每2s,sentinel節(jié)點會向redis數(shù)據(jù)節(jié)點_sentinel_:hello頻道發(fā)送該sentinel對master的判定信息 & 自己節(jié)點信息。所有sentinel節(jié)點都訂閱該頻道,也可了解到其他sentinel對master的判斷情況,作為客觀下線 & leader選舉的依據(jù)。
- 每1s,sentinel節(jié)點向redis數(shù)據(jù)節(jié)點和其余sentinel發(fā)送ping作為心跳檢測。
- 每10s,sentinel節(jié)點會向master和slave發(fā)送
- 主觀下線
- 上方定時任務,每秒一次ping,若被ping對象未能及時在
sentinel down-after-milliseconds參數(shù)內響應,該sentinel即判定被ping對象下線,此為主觀下線。 - 主觀下線時一家之言,存在誤判可能性。
- 上方定時任務,每秒一次ping,若被ping對象未能及時在
- 客觀下線:sentinel發(fā)送
sentinel is-master-down-by-addr命令,讓其他sentinel節(jié)點也判定master情況,超過quorum個數(shù),此時的下線即為客觀下線,可信度很高。 - sentinel節(jié)點leader選舉
- 選舉出leader后,才能對認定的客觀下線master節(jié)點執(zhí)行故障轉移操作。
- 選舉leader基于Raft算法,大致邏輯為:
- 所有sentinel都可以成為leader,當它確認master主觀下線時,向其他sentinel發(fā)送
sentinel is-master-down-by-addr; - 若其他sentinel未同意過別人的該請求,就會同意本次請求(先到先得),否則就拒絕;
- 如果該sentinel發(fā)現(xiàn)自己的票數(shù)大于半數(shù),那么它將成為leader。
- 所有sentinel都可以成為leader,當它確認master主觀下線時,向其他sentinel發(fā)送
- 故障轉移
- 從slave中選擇新的master,基于
slave-priority參數(shù); - 若
slave-priority無法選出,根據(jù)復制偏移量最大的優(yōu)先原則; - 若依然無法選舉出結果,選擇runid最小的slave節(jié)點,即誰先啟動誰做master。
- 從slave中選擇新的master,基于
- 三個定時任務
總結:相對于簡單的redis主從,哨兵模式可以只能地自動完成主從切換,基于jedis時不需要配置vip,使用sentinelPool即可。
4. 集群模式
a. 基礎部分
- 概述:redis cluster是分布式解決方案,于3.0版本推出,可解決單機內存、并發(fā)、流量的瓶頸問題。
- 分區(qū):基于hash分區(qū)(非一致性hash),具體為虛擬槽分區(qū)(0 - 16383個slots)。
- 每個redis節(jié)點接收一部分的slots,若cluster共5個節(jié)點,每個節(jié)點分到3276個slots;
- 計算公式:slot = CRC16(key) & 16383(取模)。
- 潛在問題
- 批量操作:對于mget mset之類的key批量操作僅在針對于同一個slot時可進行,事務操作同樣受限,必須是指向同一個節(jié)點的key才可進行事務操作,pipeline相對不影響。
- 負載不均:key是最小顆粒度,若key是hash或者list等big key,均指向同一個slot,會一定程度負載不均衡;
- 結構問題:cluster僅有一個db 0,不支持16個db;復制結構只有一層,不存在樹形拓撲結構。
- masterauth & requirepass的區(qū)別
- masterauth:slave節(jié)點數(shù)據(jù)同步時,需要用到這個密碼來訪問master節(jié)點;
- requirepass:每個node自己登錄時的密碼,可以各不相同;
- 注意:slave節(jié)點配置的masterauth,需要和master節(jié)點的requirepass一致,為防止混亂,建議全部都設成一樣。理論上master上不用設置masterauth,但是主從身份可能會切換,所以一般都會配置上。
b. 集群新建
-
節(jié)點握手:啟動集群后的節(jié)點后它們彼此并不互相知曉。節(jié)點通過gossip協(xié)議彼此通信完成節(jié)點握手,具體步驟如下方。
- 客戶端發(fā)起命令
cluster meet <ip> <port>,讓其與對應的ip port對象握手通信。 - 該對象收到meet消息,保存發(fā)起方的節(jié)點信息,并回復pong。
- 兩者通過定期ping pong命令保持心跳通信。
- 注意,僅需在集群內任一節(jié)點執(zhí)行
cluster meet <ip> <port>即可,握手狀態(tài)胡通過消息在集群中傳播,其他節(jié)點會自動發(fā)現(xiàn)后續(xù)加入集群的新節(jié)點,并發(fā)起握手流程。最終,執(zhí)行cluster nodes確認全部節(jié)點都彼此感知并組成集群。
- 客戶端發(fā)起命令
-
分配槽
- 概述:redis集群將所有數(shù)據(jù)映射值16384個slots中,所以每個key都會掉落到某個slot中。
- 初始分配命令:登陸不同節(jié)點各自分配工作,node1上進行
cluster addslots {0..5461},node2上cluster addslots {5462..10922},node3上cluster addslots {10923.。16383}。 - 主從關系確立:剩余3個節(jié)點需要完成和前面3個節(jié)點的主從關系建立,使用命令
cluster replicate <nodeId>。
總結:redis官方提供redis-trib.rb工具可幫助更快速搭建集群,使用命令
redis-trib.rb create --replicas <node1ip:port> <node...>。
c. 節(jié)點通信
- 概述:分布式結構需要維護節(jié)點的metadata,一般采用方式有集中式和P2P方式。redis cluster采用的是Gossip協(xié)議,是P2P方式,讓節(jié)點彼此不斷通信交換信息。
- 過程說明
- 集群中的每個節(jié)點會單獨開辟一個tcp通道用于節(jié)點間的互相通信,一般是16379(服務端口+1w)。
- 每個節(jié)點在固定周期內會通過特定規(guī)則選擇幾個節(jié)點發(fā)送ping消息。
- 接收到ping消息的節(jié)點會返回pong消息。
- Gossip協(xié)議
- 主要職責:作為集群中信息交換的載體。
- 類別:ping,pong,meet以及fail,ping&pong是最頻繁的消息用于保持心跳,meet是通知新節(jié)點加入,fail則是下線時。
d. 集群伸縮
- 概述:在不影響提供服務前提下,完成redis集群的節(jié)點增加或下線,其主要是內容是slots在不同節(jié)點間的靈活移動。
- 擴容集群步驟
- 準備新節(jié)點:細節(jié)可參考初次啟動集群節(jié)點的內容。
- 加入集群:依然使用
cluster meet <ip> <port>實現(xiàn)。加入集群后,新加入的節(jié)點都是master的角色,且沒有分配槽。 - 注意點:建議避免使用
cluster meet完成新節(jié)點加入集群,使用redis-trib.rb工具更穩(wěn)定、適合生產(chǎn)環(huán)境,具體命令為redis-trib.rb add-node newhost:port existingHost:port。 - 槽 & 數(shù)據(jù)遷移:在上方操作完成后,開始進行slots的數(shù)據(jù)遷移,按slot逐個完成遷移工作,可通過pipeline提升網(wǎng)絡利用率。實現(xiàn)槽遷移可用命令
redis-trib.rb reshard host:port --from <源節(jié)點id,若有多個節(jié)點使用逗號分隔> --to<目標節(jié)點id,只可寫一個> --slots <遷移槽總數(shù)量> --yes --timeout <migrate操作超時時間ms,默認6w> --pipeline <單次遷移key的數(shù)量,默認10>。
- 收縮集群:步驟類似擴容集群,但需先完成遷移工作后再下線,使用
redis-trib.rb del-node ip:port nodeId完成忘記節(jié)點的操作,不建議于生產(chǎn)環(huán)境使用cluster forget進行忘記節(jié)點的操作。
e. 請求路由
- 概述:為追求性能,客戶端連接集群未采用代理方式,是直連節(jié)點的。
- 請求重定向:redis集群收到任何key相關命令,首先計算key對應的slot,根據(jù)slot找到具體的節(jié)點。若不是本節(jié)點,回復MOVE重定向錯誤,通知客戶端找到正確的節(jié)點。
- smart客戶端:該客戶端維護slot --> node映射關系,本地即可實現(xiàn)key到節(jié)點的查找,MOVE協(xié)助smart更新映射關系。
- ASK重定向:redis集群在線遷移slots和數(shù)據(jù)完成水平擴容,遷移過程中會存在一部分數(shù)據(jù)在源節(jié)點,一部分在目標節(jié)點。
- 數(shù)據(jù)仍在源節(jié)點:基于slots緩存的映射關系,用戶請求的key對象能被正常返回。
- 數(shù)據(jù)已遷移至目標節(jié)點:用戶請求的key根據(jù)計算會找到源節(jié)點,但實際key已經(jīng)遷移到目標節(jié)點,返回ASK重定向異常。
f. 故障發(fā)現(xiàn) & 恢復
- 故障發(fā)現(xiàn) & 恢復
- 主觀下線:類似哨兵模式sentinel下的概念,主觀是僅單節(jié)點認定某節(jié)點下線,認為其超過timeout閾值未響應。
- 客觀下線
- 概述:多節(jié)點共同判定某節(jié)點下線,一般是半數(shù)以上有槽節(jié)點投票結果。
- 流程:通知故障節(jié)點下線并生效,讓故障節(jié)點的從節(jié)點進行故障轉移操作——升級成master。
- 故障恢復
- 資格確認:查看slave和故障master的最后斷開時間,判斷其是否有資格升級成master。
- 選舉:具備資格后,更新觸發(fā)故障選舉時間,待時間達到后開始選舉,觸發(fā)節(jié)點的配置紀元更新(該數(shù)值只增不減)。
g. 集群運維事項
- 完整性:若slots未全部分配完畢,則此時集群不可用。即便僅一個slot未分配,也會導致集群不可用的狀態(tài)。
- 集群規(guī)模:基于帶寬消耗考慮,帶寬消耗主要位于gossip協(xié)議維系集群時和讀寫命令。官方建議集群規(guī)模在1000以內,避免耽擱集群體量過大。
- 集群傾斜
- 數(shù)據(jù)傾斜:節(jié)點和slots間分配不均、不同slots包含的key數(shù)量差異過大、集合對象中包含元素過多(bigkey) & 節(jié)點間內存配置不一致。
- 請求傾斜:常出現(xiàn)于hotkey場景下,盡量避免hmget、hgetall這類高復雜度操作導致該類問題影響放大。一般可使用本地緩存降低hotkey調用。
- 集群讀寫分離:集群一般不做讀寫分離,若壓力過大可直接擴容主節(jié)點數(shù)量。默認情況下,集群中的slave不接受任何外來讀寫請求。
- 故障轉移
- master變更:主節(jié)點需要更換時,可先手動將slave升級,然后再將原來master下線升級。
- 強制故障轉移:若master & slave同時故障、master & slave復制出現(xiàn)問題(slave不具備資格升級)、集群半數(shù)master故障時,需要強制故障轉移。使用的命令有兩個,
cluster failover force&cluster failover takeover。后者盡可能避免使用,一般僅在大多數(shù)主節(jié)點故障時采用。
h. 分布式批量操作優(yōu)化
- 優(yōu)化方法
- 客戶端n次get:n次網(wǎng)絡+n次get命令。
- 客戶端1次pipeline get:1次網(wǎng)絡+n次get命令。
- 客戶端1次mget:1次網(wǎng)絡+1次get命令。
- 對應場景
- 串行命令:n個key均勻分布在多個節(jié)點,只可使用客戶端n次get的方法。
- 串行IO:基于集群中的Smart客戶端,獲得key對應的slot所在的節(jié)點,去往一個節(jié)點的命令一起發(fā)送,但是串行一個個發(fā)往不同節(jié)點上,實現(xiàn)了客戶端1次pipeline get。
- 并行IO:思路同上,最后發(fā)送命令時優(yōu)化成并行的模式。
- hash_tag:利用hash_tag把多個key強制分配到一個redis節(jié)點,這樣就可以使用mget實現(xiàn)客戶端1次mget,這樣最高效但是數(shù)據(jù)分發(fā)易不均勻。