redis cluster 之master 選舉過程

2021-01-16 友蘭之家

在redis 3.0版本後,官方推出了redis cluster 分布式解決方案,當一個redis節點掛了可以快速地切換到另一個節點。當遇到單機內存、並發等瓶頸時,可以採用分布式方案要解決問題.

redis-cluster架構中,被設計成共有16384(2的14次方)個hash slot。每個master分得一部分slot,其算法為:hash_slot = crc16(key) mod 16384 ,這就找到對應slot。群集至少需要3主3從,且每個實例使用不同的配置文件。

在cluster架構下,默認的,一般redis-master用於接收讀寫,而redis-slave則用於備份,當有請求是在向slave發起時,會直接重定向到對應key所在的master來處理。但如果不介意讀取的是redis-cluster中有可能過期的數據並且對寫請求不感興趣時,則亦可通過readonly命令,將slave設置成可讀,然後通過slave獲取相關的key,達到讀寫分離。

redis-cluster 不可用 的情況:

1 集群主庫半數宕機(無論是否從庫存活)

2 集群某一節點的主從全數宕機。

當某個master掛掉後,在cluster集群仍然可用的前提下,由於某個master可能有多個slave,某個salve將提升為master節點,那麼就會存在競爭,那麼此時它們的選舉機制是怎樣的呢?於是我們進入了正題:

要理解下面的過程我們需要了解一些概念:

currentEpoch:

這是一個集群狀態相關的概念,可以當作記錄集群狀態變更的遞增版本號。每個集群節點,都會通過 server.cluster->currentEpoch 記錄當前的 currentEpoch。

集群節點創建時,不管是 master 還是 slave,都置 currentEpoch 為 0。當前節點接收到來自其他節點的包時,如果發送者的 currentEpoch(消息頭部會包含發送者的 currentEpoch)大於當前節點的currentEpoch,那麼當前節點會更新 currentEpoch 為發送者的 currentEpoch。因此,集群中所有節點的 currentEpoch 最終會達成一致,相當於對集群狀態的認知達成了一致。

其過程如下:

1.slave發現自己的master變為FAIL

2.發起選舉前,slave先給自己的epoch(即currentEpoch)增一,然後請求其它master給自己投票。slave是通過廣播FAILOVER_AUTH_REQUEST包給集中的每一個masters。

3.slave發起投票後,會等待至少兩倍NODE_TIMEOUT時長接收投票結果,不管NODE_TIMEOUT何值,也至少會等待2秒。

4.master接收投票後給slave響應FAILOVER_AUTH_ACK,並且在(NODE_TIMEOUT*2)時間內不會給同一master的其它slave投票。

5.如果slave收到FAILOVER_AUTH_ACK響應的epoch值小於自己的epoch,則會直接丟棄。一旦slave收到多數master的FAILOVER_AUTH_ACK,則聲明自己贏得了選舉。

6.如果slave在兩倍的NODE_TIMEOUT時間內(至少2秒)未贏得選舉,則放棄本次選舉,然後在四倍NODE_TIMEOUT時間(至少4秒)後重新發起選舉。

只所以強制延遲至少0.5秒選舉,是為確保master的fail狀態在整個集群內傳開,否則可能只有小部分master知曉,而master只會給處於fail狀態的master的slaves投票。如果一個slave的master狀態不是fail,則其它master不會給它投票,Redis通過八卦協議(即Gossip協議,也叫謠言協議)傳播fail。而在固定延遲上再加一個隨機延遲,是為了避免多個slaves同時發起選舉。

延遲計算公式:

DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

SLAVE_RANK表示此slave已經從master複製數據的總量的rank。Rank越小代表已複製的數據越新。這種方式下,持有最新數據的slave將會首先發起選舉(理論上)。

相關焦點

  • redis cluster 集群管理工具
    前言在redis源碼編譯的時候,在src目錄下會有一個redis-trib.rb的腳本,這個腳本是ruby寫的,用於管理redis cluster。info命令也是先執行load_cluster_info_from_node獲取完整的集群信息。/opt/redis/bin/redis-trib.rb info 127.0.0.1:80013、check檢查集群:檢查集群狀態的命令,沒有其他參數,只需要選擇一個集群中的一個節點即可。
  • redis cluster-cluster 命令手動管理redis集群
    使用cluster命令管理redis cluster集群1、列印集群的信息 CLUSTER INFO cluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail
  • 不懂Redis Cluster原理,我被同事diss了!
    圖 10:節點遷移槽數據的過程如圖 10 所示,由客戶端發起節點之間的槽數據遷移,數據從源節點往目標節點遷移:客戶端對目標節點發起準備導入槽數據的命令,讓目標節點準備好導入槽數據。這裡使用 cluster setslot {slot} importing {sourceNodeId} 命令。之後對源節點發起送命令,讓源節點準備遷出對應的槽數據。
  • Redis 3.0.0 RC4 發布,無 Redis Cluster 修復
    此版本包括關於 redis-cli 方面的新特性,一個使用 xterm 256 顏色的延遲光譜可視化工具。Reids 團隊計劃兩周後發布一個 RC 版本或者是 3.0.0 穩定版本。Reids 3.0.0.RC4 常規改進:* [FIX] redis-cli CSV output NIL spurious newline removed.
  • 機率大的 Redis 面試題(含答案)|內存|key|原子性|哈希|redis_網易...
    實現:單獨創建fork()一個子進程,將當前父進程的資料庫數據複製到子進程的內存中,然後由子進程寫入到臨時文件中,持久化的過程結束了,再用這個臨時文件替換上次的快照文件,然後子進程退出,內存釋放。  RDB是Redis默認的持久化方式。按照一定的時間周期策略把內存的數據以快照的形式保存到硬碟的二進位文件。
  • Redis教程:Redis持久化方式
    使用 Redis 附帶的 redis-check-aof 程序,對原來的 AOF 文件進行修復: redis-check-aof –x(可選)使用 di -u 對比修復後的 AOF 文件和原始 AOF 文件的備份,查看兩個文件之間的不同之處。重啟 Redis 伺服器,等待伺服器載入修復後的 AOF 文件,並進行數據恢復。
  • 大數據必學:redis深入了解 Redis 的持久化機制(RDB、AOF)
    因為 redis是一個內存資料庫,所有數據都存儲在內存中,而且內存中的數據非常容易丟失,所以 redis的數據持久化就變得非常重要, redis提供了兩種數據持久化方法,分別用於 RDB和 AOF,而 redis默認用於 RDB的數據持久化方法。
  • 使用ClusterLabs實現Asterisk/FreeSWITCH集群部署
    具體支持功能包括(官方原文):The ClusterLabs stack, incorporating Corosync and Pacemaker defines an Open Source, High Availability cluster offering suitable for both small and large
  • redis - aof持久化介紹
    AOF簡介redis持久化存儲的方式有rdb序列化存儲和aof(append only file)。aof就是將操作和數據以格式化指令的方式追加到操作日誌的尾部,在append操作返回後,才進行實際的數據變更。
  • 《蹲坑學K8S》之22-2:Kubernetes授權機制
    1、創建clusterrole[root@k8s-master ~]# vim test-clusterrole.yaml添加:apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: test-clusterrolerules
  • Python使用redis存儲對象
    Python總的對象存儲到redis中默認為字符串,那麼如何存儲對象呢?下面就看看如何直接將Python中對象存儲到redis中先寫個測試redis是否正常連接上import rediscache = redis.StrictRedis('172.20.0.227',6379)
  • Redis持久化和備份
    比如如下命令redis 127.0.0.1:6379> set key1 HelloOKredis 127.0.0.1:6379> append key1 " World!"(integer) 12redis 127.0.0.1:6379> del key1(integer) 1redis 127.0.0.1:6379> del non_existing_key(integer) 0在AOF中存儲如下$ cat appendonly.aof*2$6SELECT$10*3$3set$4key1$5Hello*3$6append$4key1$7 World
  • Redis如何存儲和計算一億用戶的活躍度
    2.如何滿足搜索,redis是一個鍵值對的內存結構,只能根據key來進行定位value值,無法做到像elastic search那樣對文檔進行倒排索引快速全文檢索。redis其實有這種數據結構的,可以以很少的空間來存儲大量的信息。
  • 微信附近的人,用redis也能實現?(GEO)
    作為一個程序猿任何問題應該都有一個思考的過程,而不是直接看結論,接下來大家一步一步的思考,直到問題解決。geo 的方式來實現redis geo 介紹首先我們需要注意的是,redis geo 是 3.2 版本才有的,所以需要用這個功能的朋友記得更新 redis 的版本其實 redis geo 只有 6 個操作命令,知道這些命令基本思路就出來了GEOADD:增加某個地理位置的坐標GEOPOS:獲取某個地理位置的坐標GEODIST:獲取兩個地理位置的距離
  • Redis RDB與AOF模式下的持久化原理
    前言:在此之前,如果還不了解Redis的,或者不知道怎麼使用Redis,可以參考官網網站:https://redis.io/documentation自行學習,本文主要針對Redis的核心點之一:RDB和AOF持久化模式進行展開。
  • Redis中的過期鍵以及如何刪除的?
    1 伺服器中的資料庫Redis伺服器將所有資料庫都保存在伺服器狀態redis.h/redisServer結構的db數組中,db數組的每個項都是一個redis.h/redisDb結構,每個redisDb結構代表一個資料庫:struct redisServer {//一個數組,保存著伺服器中的所有資料庫redisDb *db;
  • 詳解Redis中兩種持久化機制RDB和AOF(面試常問,工作常用)
    redis是一個內存資料庫,數據保存在內存中,但是我們都知道內存的數據變化是很快的,也容易發生丟失。幸好Redis還為我們提供了持久化的機制,分別是RDB(Redis DataBase)和AOF(Append Only File)。在這裡假設你已經了解了redis的基礎語法,某字母網站都有很好的教程,可以去看。基本使用的文章就不寫了,都是一些常用的命令。
  • GO analysis using clusterProfiler
    clusterProfiler supports over-representation test and gene set enrichment analysis of Gene Ontology. It supports GO annotation from OrgDb object, GMT file and user's own data.
  • Star Cluster R136 Breaks Out
    Virginia Explanation: In the center of nearby star-forming region lies a huge cluster containing some of the largest, hottest, and most massive stars known.