Redis哨兵模式(Sentinel、1主2從3哨兵6臺伺服器配置實戰、客戶端呼叫、日誌解析、主觀下線、客觀下線、仲裁、腦裂問題、哨兵長與從節點投票選舉過程與原理)

小松聊PHP进阶發表於2024-06-24

哨兵模式

  • 官方文件:https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel
  • 關聯部落格:Redis主從複製(下文能用到)
  • 極簡概括:自動監控Redis主節點是否故障的一種方案,若主節點故障,則Redis會根據投票數自動將從庫切換為主庫(這個過程,叫仲裁)。
  • 解決問題:在主從複製的架構模式下,Redis主節點掛掉後,從節點無任何補償操作,無人工干預的情況下導致整個快取鏈路的寫功能喪失。而哨兵模式有哨兵看守機制,可以做到主機的檢測與自動切換從機為主機的功能。
  • 適用場景:對於需要7 * 24高可用,且公司原意投資相關運維成本的服務端應用。畢竟作為哨兵節點的Redis例項,將無法使用快取服務,只能作為哨兵,而且要求哨兵數量往往是奇數個。
  • 優點:
    • 降低運維成本:強大的高可用機制,適當降低運維成本。
    • 自動恢復機制:當主節點掛掉後,哨兵會自動選出一個從節點作為主節點,繼續對外提供服務,無人值守。
  • 缺點:
    • 場景限制:小型公司Redis都可以不用,中型公司也不一定能用到Redis主從,更何況是哨兵這麼嚴謹的運維策略。
    • 資金問題:Redis需要堆多個伺服器,對公司而言是不小的支出,有一定門檻。
    • 延遲問題:主節點掛掉時,雖然可以做到自動切換,但是多個哨兵認為Redis能夠客觀下線時,這個過程需要時間的,雖然可以調整,但是這個時間內的Redis寫操作是失效的,因此有了叢集策略。
    • 資料丟失問題:Redis主從是非同步複製,哨兵只是增加了自動化的切換功能,沒有像MySQL的redo log機制,無法保證資料100%不丟失。
    • 會引發腦裂問題(下文有說)。
  • 誤區:哨兵是哨兵,叢集是叢集,兩者無關。哨兵是主從複製架構的高可用最佳化方案,不是叢集部署的高可用的方案。
  • 訪問流程:由原先的程式語言客戶端訪問Redis主節點或從節點,變成了客戶端訪問哨兵節點(通常不止一個哨兵,有奇數個哨兵組成一個哨兵叢集,奇數好投票),由哨兵節點告訴客戶端訪問那個主節點或從節點,從而區分讀寫操作。

實操(1主+2從+3哨)

  • 三哨理由:一個小區也不只一個保安,至少2個保安輪班倒。但是哨兵有類似投票機制,最好用奇數個哨兵。
  • 環境決策:部署3個哨兵+1個Master+2個Slave,共6臺伺服器。
  • Docker方案:當記憶體扛不住的時候可以用這個,但是拉映象時發現被牆了(國內混蛋專家搞的混蛋規則),映象拉不下來,本地也沒有,棄用了這條路線。
  • 執行環境:CentOS 7.6,每個系統分配256M記憶體,Linux可輕鬆啟動,共佔用記憶體1.5GB,裝置能承受,但磁碟佔用挺高(特別是開機時),每個Redis例項都配置好了遠端連線功能(防火牆、遠端連線許可權、保護模式,都配置到位)。
  • IP分配:192.168.0.180(主)、192.168.0.181(從1)、192.168.0.182(從2)、192.168.0.183(哨1)、192.168.0.184(哨2)、192.168.0.185(哨3),如圖
                  	 192.168.0.183                           192.168.0.181
                  /                \                      /
              	/                    \                  /
               /                      \               /
192.168.0.xxx  -->-> 192.168.0.184 ---> 192.168.0.180
               \                      /               \
                 \                   /                  \
                   \                /                     \  
                     192.168.0.185                           192.168.0.182
  • 主要配置說明:
配置3臺哨兵:
高版本Redis自帶sentinel.conf檔案,可直接用。
目前用的5,沒有獨立的配置檔案,可在redis.conf中配置如下:
sentinel monitor 主節點名  主節點IP 主節點埠 確認客觀下線的最少哨兵數量。    // 配置連結,用於定位主機網路位置。
sentinel auth-pass 主節點名  主節點密碼        //配置主機密碼
sentinel down-after-milliseconds 主節點名 毫秒 //配置心跳失去連線多少毫秒後,讓哨兵認為主機當機
sentinel failover-timeout 主節點名 毫秒        //配置執行故障轉移所需的超時時間
sentinel parallel-syncs 主節點名 數量          //切換新的主節點之後,可同時同步其餘從節點的個數,數字越小效能越低。
其它配置不常用,可參考官方手冊。

對於sentinel monitor 配置項,“確認客觀下線的最少哨兵數量”引數的介紹:
至少有N個哨兵節點,認為主節點有故障,才會將其下線。
由於哨兵節點自身負載問題,或網路鏈路有抖動問題,這會直接影響Redis哨兵檢測主節點的心跳,誤認為主節點是當機。
但是容易有誤判,所以設定了指定的容錯額度,減少誤判率。
  • 實操:
第一步,先配置1主(不用配置)2從(需要在192.168.0.181和192.168.0.182上):
我之前寫過完整文章,可參考https://blog.csdn.net/weixin_42100387/article/details/139667697

vim /usr/local/redis/etc/redis.conf
#配置主節點IP和埠
replicaof 192.168.0.180 6379
#配置主節點密碼
masterauth 123456

之後重啟redis

需要注意,必須把每個從機的密碼設定一致,方便哨兵模式主從切換例項,避免整個快取模組故障。



第二步,配置3哨兵:
以Redis 5為例,3臺哨兵節點(192.168.0.183~185)配置以下主要內容,其餘配置可按需新增(因為不配置也有預設值,不會導致錯誤):
補充:一個哨兵是可以監控多個master的,但是這對於開發幾乎用不上。
firewall-cmd --add-port=26379/tcp --zone=public --permanent && systemctl restart firewalld
vim /usr/local/redis/etc/sentinel.conf
bind 0.0.0.0
#哨兵預設埠
port 26379
daemonize yes
protected-mode no
pidfile /usr/local/redis/redis_26379.pid
logfile /usr/local/redis/redis_26379.log
sentinel monitor zs_master 192.168.0.180 6379 2
sentinel auth-pass zs_master 123456

之後啟動哨兵,用以下二選一命令的方式
/usr/local/redis/bin/redis-sentinel /usr/local/redis/etc/sentinel.conf
/usr/local/redis/bin/redis-server   /usr/local/redis/etc/sentinel.conf --sentinel

啟動後,redis 會為sentinel.conf額外增加如下配置:
sentinel myid 3feb02e7fd5a96152e217b76f11e72236c23668c
sentinel deny-scripts-reconfig yes
# Generated by CONFIG REWRITE
dir "/usr/local/redis/etc"
sentinel config-epoch zs_master 0
sentinel leader-epoch zs_master 0
sentinel known-replica zs_master 192.168.0.182 6379
sentinel known-replica zs_master 192.168.0.181 6379
sentinel current-epoch 0

它們的含義分別是:
sentinel myid:起個唯一標識,方便定位哨兵,類比MySQL表id。
sentinel deny-scripts-reconfig yes: 拒絕透過指令碼進行配置更改,這有助於提高安全性,防止非授權的更改。
dir "/usr/local/redis/etc": 指定rdb檔案的位置。
sentinel config-epoch zs_master 0: 記錄主節點zs_master的情況,用於判斷哨兵配置的更新情況。
sentinel leader-epoch zs_master 0: 記錄主節點zs_master的情況,用於判斷哨兵的領導者。
sentinel known-replica zs_master 192.168.0.182 6379: 記錄已知的從節點,這裡指定了IP地址和埠號。
sentinel current-epoch 0: 記錄當前的紀元(直譯就這意思),用於標識哨兵配置的更新情況。



第三步,檢測1主2從是否能正常使用
可在主節點Redis會話中執行 set a 123,從節點執行 get a 判斷主從是否正常複製。



第四步,檢測3臺哨兵是否啟動(3臺裝置分別執行,逐一檢測):
ps aux | grep redis
root      81041  0.4  0.5 153996  2788 ?        Ssl  00:34   0:00 /usr/local/redis/bin/redis-sentinel 0.0.0.0:26379 [sentinel]
root      81084  0.0  0.2 112828   992 pts/0    R+   00:35   0:00 grep --color=auto redis

netstat -nlp | grep redis
tcp        0      0 0.0.0.0:26379           0.0.0.0:*               LISTEN      81041/redis-sentin

模擬主節點故障

經過實測:

  • 主節點執行shutdown模擬當機,半分鐘內,Redis哨兵自動完成了主節點的下線,並將某個從節點切換為主節點。
  • 從節點升級為主節點的節點,以及其它從節點,的配置檔案都會被強制更改,作用到配置檔案,是持久化的。
  • 哨兵切換流程執行完畢後原主節點恢復訪問,那麼原主節點會變成從節點,不會因為本身的恢復,就再次改為主節點。
  • 一些情情況下,當掛掉的主節點再次啟動時,可成功啟動,但是redis的機制會把master-auth配置項幹丟掉,造成啟動之後(變為從節點)連不上主節點的情況。

哨兵對應日誌說明

  • 由於Redis哨兵模式趨向於自動化運維,所以日常日誌的排查七分重要,故在此說明其中1個哨兵(192.168.0.184)的日誌記錄概況(最起碼要看懂【何時主節點掛】、【讓誰做主節點】)。
  • 速查方法(根據關鍵字搜尋,若搜尋出多個值,最後一個為最新):
    • 查詢何時主節點掛:odown master 原主節點名 原主節點IP 原主節點埠 #quorum
    • 查詢讓誰做主節點:+switch-master 原主節點名 原主節點IP 原主節點埠(後面緊跟新主節點)
  • 哨兵啟動時:
Redis哨兵初始化
99136:X 19 Jun 2024 05:58:54.697 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
99136:X 19 Jun 2024 05:58:54.697 # Redis version=5.0.9, bits=64, commit=00000000, modified=0, pid=99136, just started
99136:X 19 Jun 2024 05:58:54.697 # Configuration loaded
99137:X 19 Jun 2024 05:58:54.701 * Running mode=sentinel, port=26379.
99137:X 19 Jun 2024 05:58:54.701 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
99137:X 19 Jun 2024 05:58:54.702 # Sentinel ID is 0da5ef8126894b04e2572c4f2f9e1e636543ceee
主節點從節點資訊獲取
99137:X 19 Jun 2024 05:58:54.702 # +monitor master zs_master 192.168.0.180 6379 quorum 2
99137:X 19 Jun 2024 05:58:54.720 * +slave slave 192.168.0.181:6379 192.168.0.181 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:58:54.722 * +slave slave 192.168.0.182:6379 192.168.0.182 6379 @ zs_master 192.168.0.180 6379
新增了兩個哨兵
99137:X 19 Jun 2024 05:58:56.059 * +sentinel sentinel 91e7adffd0d7fc08fc1eb622001eb78b7c230901 192.168.0.183 26379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:58:59.359 * +sentinel sentinel cadd108977e5634179172b6a2f84f4712f2c9185 192.168.0.185 26379 @ zs_master 192.168.0.180 6379
  • 主節點當機時:
當前哨兵認為主機已下線,主觀下線。
99137:X 19 Jun 2024 05:59:59.572 # +sdown master zs_master 192.168.0.180 6379
其它哨兵也認為主機已下線,並達到了sentinel monitor設定的閾值,主觀下線升級為客觀下線
99137:X 19 Jun 2024 05:59:59.627 # +odown master zs_master 192.168.0.180 6379 #quorum 2/2
故障切換,當前切換,讓0da5ef8126894b04e2572c4f2f9e1e636543ceee 哨兵說了算,其餘哨兵投票。
99137:X 19 Jun 2024 05:59:59.627 # +new-epoch 1
99137:X 19 Jun 2024 05:59:59.627 # +try-failover master zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:59:59.628 # +vote-for-leader 0da5ef8126894b04e2572c4f2f9e1e636543ceee 1
99137:X 19 Jun 2024 05:59:59.630 # cadd108977e5634179172b6a2f84f4712f2c9185 voted for 0da5ef8126894b04e2572c4f2f9e1e636543ceee 1
99137:X 19 Jun 2024 05:59:59.630 # 91e7adffd0d7fc08fc1eb622001eb78b7c230901 voted for 0da5ef8126894b04e2572c4f2f9e1e636543ceee 1
選擇192.168.0.182作為主節點,客觀下線老主節點,並將180的主節點轉移為182的主節點,換人和交換權利的動作不重複。
99137:X 19 Jun 2024 05:59:59.732 # +elected-leader master zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:59:59.732 # +failover-state-select-slave master zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:59:59.837 # +selected-slave slave 192.168.0.182:6379 192.168.0.182 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:59:59.837 * +failover-state-send-slaveof-noone slave 192.168.0.182:6379 192.168.0.182 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 05:59:59.907 * +failover-state-wait-promotion slave 192.168.0.182:6379 192.168.0.182 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:00.239 # +promoted-slave slave 192.168.0.182:6379 192.168.0.182 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:00.239 # +failover-state-reconf-slaves master zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:00.298 * +slave-reconf-sent slave 192.168.0.181:6379 192.168.0.181 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:00.788 # -odown master zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:01.280 * +slave-reconf-inprog slave 192.168.0.181:6379 192.168.0.181 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:01.281 * +slave-reconf-done slave 192.168.0.181:6379 192.168.0.181 6379 @ zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:01.353 # +failover-end master zs_master 192.168.0.180 6379
99137:X 19 Jun 2024 06:00:01.353 # +switch-master zs_master 192.168.0.180 6379 192.168.0.182 6379
將180,181節點,當做從節點處理。
99137:X 19 Jun 2024 06:00:01.354 * +slave slave 192.168.0.181:6379 192.168.0.181 6379 @ zs_master 192.168.0.182 6379
99137:X 19 Jun 2024 06:00:01.354 * +slave slave 192.168.0.180:6379 192.168.0.180 6379 @ zs_master 192.168.0.182 6379
當前哨兵發現180從節點仍不能用,主觀下線。
99137:X 19 Jun 2024 06:00:31.393 # +sdown slave 192.168.0.180:6379 192.168.0.180 6379 @ zs_master 192.168.0.182 6379

程式語言呼叫

  • 以原生PHP為例:
// 建立Redis哨兵物件,透過這個物件獲取主節點的地址,這裡是寫死的,可以寫成陣列,隨機訪問1個節點,用於減輕壓力。
$sentinel = new RedisSentinel('tcp://192.168.0.183', 26379);
//主機名
$master = $sentinel->getMasterAddrByName('zs_master');

if(! $master) {
    echo '主節點獲取失敗';
    die;
}


//獲取到的主節點地址進行寫操作
$redis = new Redis();
$redis->connect($master[0], $master[1]);
$redis->auth('123456');
$redis->set('key', 'val');


//從節點讀操作。
$slave = $sentinel->slaves('zs_master');
if(empty($slave)) {
    echo '從節點獲取失敗';
    die;
}

//隨機從節點配置陣列的下標,使其讀寫趨向於均衡,防止訪問壓力傾斜
$slave_arr_key = mt_rand(0, count($slave));

//這塊的從節點配置不能寫死,一定要寫活,萬一這裡的從節點,變成了主節點呢?
$redis->connect($slave[$slave_arr_key]['ip'], $slave[$slave_arr_key]['port']);
$redis->auth('123456');
$res = $redis->get('key');
print_r($res);


// 關閉連線
$redis->close();
  • 以Laravel為例:
    Laravel官網並未搜尋對應的解決方案,想要在Laravel內用Redis哨兵模式,可原生去實現,或者使用某些composer包,例如monospice/laravel-redis-sentinel-drivers,詳細內容可看官方文件:
    Github地址:https://github.com/monospice/laravel-redis-sentinel-drivers
    Packagist地址:https://packagist.org/packages/monospice/laravel-redis-sentinel-drivers
composer require monospice/laravel-redis-sentinel-drivers

Laravel5.5以下版本需要再config/app.php中配置如下內容
'providers' => [
    ...
    Monospice\LaravelRedisSentinel\RedisSentinelServiceProvider::class,
    ...
],

在config/database.php的Redis段的同級中新增,這是演示,生產環境推薦引數寫活
這外掛支援直接配置到.env,不用配config,但是一旦執行php artisan optimize加速,那麼env('config_key')將會是null,所以不用。
    'redis-sentinel' => [
        'default' => [
            ['host' => '192.168.0.183', 'port' => 26379,],
            ['host' => '192.168.0.184', 'port' => 26379,],
            ['host' => '192.168.0.185', 'port' => 26379,],
        ],

        'options' => [
        //主機名
        'service' =>  'zs_master',
        'parameters' => [
            'password' => '123456',
            'database' => 0,
        ],
    ],


若要配置Redos Facdeds:
.env檔案新增REDIS_DRIVER=redis-sentinel
這個不用配置config,因為沒有地方配置,外掛直接讀取env檔案,測試php artisan optimize,發現能照常讀取。


若要配置Cache Facdeds:
config/cache.php的'default' => env('CACHE_DRIVER', 'file'), 此處最好修改env,將值改為redis-sentinel
並新增:
'stores' => [ //注意層級關係
    ...
    'redis-sentinel' => [
        'driver' => 'redis-sentinel',
        'connection' => 'default',
    ],
],


若要配置Session Facdeds:
config/session.php的'driver' => env('SESSION_DRIVER', 'file'),,此處最好修改env,將值改為redis-sentinel,
並將connection項設定為'',否則報錯。


若要配置Queue佇列:
config/queue.php的'default' => env('QUEUE_CONNECTION', 'sync'),, 此處最好修改env,將值改為redis-sentinel,
並在connections項內部配置:
    'redis-sentinel' => [
        'driver' => 'redis-sentinel',
        'connection' => 'default',
        'queue' => 'default',
        'retry_after' => 90, // Laravel >= 5.4.30
        'expire' => 90,      // Laravel < 5.4.30
    ],
測試延時佇列,可正常使用。

其餘常用配置說明

  • redis.conf
    • min-replicas-to-write 1與min-replicas-max-lag 10:這個是高可用的兩個配置項,它根筷子一樣通常在一塊出現,預設是禁用的配置,配置在主節點和從節點。表示主節點一個寫操作,至少有1個確認接收,且確認回覆(ack)時間不能超過10毫秒,否則返回的既不是nil也不是0,而是錯誤異常。它能夠保證主從複製時的高可用,弊端就是若有從節點掛掉,達不到min-replicas-to-write設定的數量,主節點寫入將會報錯,導致寫功能廢掉。一般情況下,前者設定看情況,後者設定為3000~5000。
    • replica-priority 100:被選中作為從節點的優先順序,從1設定為10,從2設定為100,則主節點掛掉,從1(小的優先)優先被設定為從機。

主觀下線(Sdown)與客觀下線(Odown)

  • 主觀下線:當前(單個)哨兵認為主節點掛了,有可能沒掛。
  • 客觀下線:多個哨兵都認為主節點掛了,則主節點大機率掛了,準備開始選舉其它從節點做主節點。

仲裁(Failover)

哨兵在主節點失效時進行自動故障轉移(failover)的行為。

腦裂(Split-brain)導致的資料丟失問題

  • 分散式系統的概念:腦裂是一種在分散式系統中可能出現的情況,指當網路故障導致部分節點無法與其它節點通訊時,這些節點可能會錯誤地認為自己是系統中唯一的活躍例項,從而導致資料的不一致(一個地方每個山頭都獨立為王,那就亂了,多了個頭頭,好比腦裂了)。
  • 在哨兵模式下(極少出現):客戶端與主節點連線正常,但是哨兵與主節點連線異常,那麼哨兵可能就會讓其它從節點變為主節點,此時分散式節點中,就會有多個主節點。然而客戶端仍舊和舊的資料通訊(執行寫操作),在這個過程下,資料會丟失。
    若此時舊主節點恢復與哨兵的連線,舊主節點就會降級為從節點,舊主節點未同步的資料也會被新節點強制覆蓋。

腦裂(Split-brain)導致的資料丟失原因

  • 感謝IT老奇的架構600講:https://www.bilibili.com/video/BV1eF41147iL/?vd_source=19da1fcedca1050975549448303b95c2
  • 背景:接上文,因為腦裂問題引發的哨兵模式自動故障轉移(failover)的行為(仲裁),,舊的主節點,有著最近的進度。
  • 過程:當這個舊主節點與哨兵恢復連線後,並且已經有新的主節點誕生,舊主節點會被降級為從節點。
  • 資料丟失內部機制:舊主節點,會向新的主節點申請全量資料,新主節點會透過bgsave命令,非同步生成rdb檔案,回傳到從節點,從節點拿到後先清空自身的所有資料,用一個乾淨的資料倉儲承接主節點發來的資料,這個清空的過程,造成了資料的丟失。
  • 結論:客戶端與Redis服務端通訊期間,最新的進度沒了,資料自然也就丟失了。

腦裂(Split-brain)問題改善

由於網路的隔離,通訊無法像MySQL本地事務那樣做到幾乎完美的一致性策略,說白了哨兵與主節點的通訊斷了就是網斷了,斷了就是斷了,不可控也無規律,程式碼寫的再好也不能解決這個問題。所以這個問題的解決方案,不能用解決修飾,用改善修飾會更好。

可在主節點和其它從節點新增min-replicas-to-write 與min-replicas-max-lag引數去改善,引數含義上文有講。
思路就是:判斷主節點寫入資料時從節點傳送ack的數量,以及延遲,若發生腦裂,則主節點數量+1,從節點數量-1,達不到min-replicas-to-write閾值時,就會報錯。這也會導致快取寫功能不可用,將異常兜底下推到程式碼層。

哨兵監控主節點(哨兵切換步驟0)

哨兵探測主節點是否異常是用的心跳機制,就是每隔一段時間,向主節點傳送ping進而保持連線。

哨兵長(Zhang)選舉(哨兵切換步驟1)

  • 動作:當主節點掛掉,哨兵進行選舉主節點時,實際上進行了兩步:第一步,哨兵會投票選舉一個哨兵長,第二步,哨兵長選舉主節點。
  • 選舉演算法:Redis使用的時Raft演算法。
  • 演算法流程(個人理解):
    時序不同,數量不同會得到不同的結果,具體讀者可深入理解Raft演算法官方說明。
步驟 哨1 哨2 哨3
1 給自己投1票,將投票請求傳送給哨2哨3,告訴他們自己要成為哨兵長
2 給自己投1票,將投票請求傳送給哨1哨2,告訴他們自己要成為哨兵長
3 收到哨3請求,拒絕 收到哨3請求,同意
4 收到哨1請求,拒絕
5 1票同意 2票同意,成為哨兵長

主節點選舉(哨兵切換步驟2)

  • 引言:多個從節點,都有可能被選擇其中一個為主節點,隨機演算法可以實現,但是有更好的判斷策略,所以不用隨機,而這些策略受一些因素限制。
  • 因素1:如果發現副本伺服器與主伺服器斷開連線的時間超過所配置的主伺服器超時時間(down-after-milliseconds)的10倍,再加上從執行故障切換的哨兵的角度來看主伺服器也不可用的時間,則副本伺服器被認為不適合進行故障切換,並被跳過。
  • 因素2:優先順序:replica-priority引數,redis.conf中預設為100,開發人員根據當前例項情況可設定不同的值,有較小值的節點會被設定為主節點。
  • 因素3:進度大小:若優先順序一樣,就看進度,進度就是所謂的偏移量。偶爾受網路抖動或者其它因素影響,會有一個進度快(進度新),進度慢的,進度新的就做了主節點。若讓進度舊的做主節點,則會讓整個鏈路整體丟失小部分資料。
  • 因素4:若許可權和進度一樣,則就看Run ID,這個每個Redis例項上都會有,根據Run ID做ASICC的字典排序,最終選取一臺從節點例項做主節點。
  • 當某個從節點被哨兵選中當做主節點時,哨兵會傳送replicaof no one命令給從節點,讓其不做任何節點的從節點。

從節點換綁主節點(哨兵切換步驟3)

能走到這個階段,就說明新的主節點已經誕生,其它從節點已經有了切換主節點的目標。
哨兵使用Redis釋出/訂閱訊息功能,在主伺服器和所有從伺服器中連續廣播相關配置,直到每個節點配置完成。

相關文章