聊聊Redis中的主從同步和哨兵模式

2022-02-08 10:00:06
本篇文章帶大家深入瞭解一下Redis中的主從同步和哨兵模式,介紹一下開啟關閉主從同步、搭建啟動Sentinel的方法,希望對大家有所幫助!

主從同步

主從同步(主從複製)是 Redis 高可用服務的基石,也是多機執行中最基礎的一個。【相關推薦:Redis視訊教學

我們把主要儲存資料的節點叫做主節點 (master),把其他通過複製主節點資料的副本節點叫做從節點 (slave),如下圖所示:

1.png

Redis一個主節點可以擁有多個從節點一個從節點也可以是其他伺服器的主節點,如下圖所示:

2.png

主從同步的優點

主從同步具有以下三個優點

  • 效能方面:有了主從同步之後,可以把查詢任務分配給從伺服器用主伺服器來執行寫操作,這樣極大的提高了程式執行的效率,把所有壓力分攤到各個伺服器了;
  • 高可用:當有了主從同步之後,當主伺服器節點宕機之後,可以很迅速的把從節點提升為主節點,為 Redis 伺服器的宕機恢復節省了寶貴的時間;
  • 防止資料丟失:當主伺服器磁碟壞掉之後,其他從伺服器還保留著相關的資料,不至於資料全部丟失。

開啟主從同步

執行中設定從伺服器

Redis 執行過程中,我們可以使用 replicaof host port 命令,把自己設定為目標 IP 的從伺服器。

如果主服務設定了密碼,需要在從伺服器輸入主伺服器的密碼,使用 config set masterauth 主服務密碼 命令的方式

在執行完 replicaof 命令之後,從伺服器的資料會被清空,主服務會把它的資料副本同步給從伺服器。

啟動時設定從伺服器

可以使用命令 redis-server --port 6380 --replicaof 127.0.0.1 6379 將自己設定成目標伺服器的從伺服器。

資料同步

完整資料同步

當有新的從伺服器連線時,為了保障多個資料庫的一致性,主伺服器會執行一次 bgsave 命令生成一個 RDB 檔案,然後再以 Socket 的方式傳送給從伺服器,從伺服器收到 RDB 檔案之後再把所有的資料載入到自己的程式中,就完成了一次全量的資料同步

部分資料同步

Redis 2.8 之前每次從伺服器離線再重新上線之前,主伺服器會進行一次完整的資料同步,然後這種情況如果發生在離線時間比較短的情況下,只有少量的資料不同步卻要同步所有的資料是非常笨拙和不划算的,在 Redis 2.8 這個功能得到了優化。

Redis 2.8 的優化方法是當從服務離線之後,主伺服器會把離線之後的寫入命令,儲存在一個特定大小的佇列中,佇列是可以保證先進先出的執行順序的,當從伺服器重寫恢復上線之後,主服務會判斷離線這段時間內的命令是否還在佇列中,如果在就直接把佇列中的資料傳送給從伺服器,這樣就避免了完整同步的資源浪費。

儲存離線命令的佇列大小預設是 1MB,使用者可以自行修改佇列大小的設定項 repl-backlog-size

無盤資料同步

在第一次主從連線的時候,會先產生一個 RDB 檔案,再把 RDB 檔案傳送給從伺服器,如果主伺服器是非固態硬碟的時候,系統的 I/O 操作是非常高的。

Redis 2.8.18 新增了無盤複製功能,無盤複製功能不會在本地建立 RDB 檔案,而是會派生出一個子程序,然後由子程序通過 Socket 的方式,直接將 RDB 檔案寫入到從伺服器,這樣主伺服器就可以在不建立 RDB 檔案的情況下,完成與從伺服器的資料同步。

要使用無須複製功能,只需把設定項 repl-diskless-sync 的值設定為 yes 即可,它預設設定值為 no

查詢伺服器的角色

使用 role 命令,來查詢當前伺服器的主從角色資訊。

關閉主從同步

可以使用 replicaof no one 命令來停止從伺服器的複製。

執行了 replicaof no one 命令之後,自己就從伺服器變成主伺服器了。

伺服器型別的轉換並不會影響資料,這臺伺服器的資料將會被保留。

注意事項

資料一致性問題

當從伺服器已經完成和主服務的資料同步之後,再新增的命令會以非同步的方式傳送至從伺服器,在這個過程中主從同步會有短暫的資料不一致,如在這個非同步同步發生之前主伺服器宕機了,會造成資料不一致。

從伺服器唯讀性

預設情況下,處於複製模式的主伺服器既可以執行寫操作也可以執行讀操作,而從伺服器則只能執行讀操作。

可以在從伺服器上執行 config set replica-read-only no 命令,使從伺服器開啟寫模式,但需要注意以下幾點:

  • 在從伺服器上寫的資料不會同步到主伺服器;
  • 當鍵值相同時主伺服器上的資料可以覆蓋從伺服器;
  • 在進行完整資料同步時,從伺服器資料會被清空。

複製命令的變化

Redis 5.0 之前使用的複製命令是 slaveof,在 Redis 5.0 之後複製命令才被改為 replicaof,在高版本(Redis 5+)中我們應該儘量使用 replicaof,因為 slaveof 命令可能會被隨時廢棄掉。

哨兵模式

主從複製模式,它是屬於 Redis 多機執行的基礎,但這種模式本身存在一個致命的問題,當主節點奔潰之後,需要人工干預才能恢復 Redis 的正常使用。

我們需要一個自動的工具——Redis Sentinel(哨兵模式)來把手動的過程變成自動的,讓 Redis 擁有自動容災恢復(failover)的能力。

哨兵就相當於對主從伺服器做一個監視的任務。一旦發現主伺服器宕機了,就迅速啟動相應的規則將某一臺從伺服器升級為主伺服器,無需人工干預,更穩定更快

Redis Sentinel 的最小分配單位是一主一從。

3.png

Redis Sentinel 搭建

使用命令 ./src/redis-sentinel sentinel.conf 來啟動 Sentinel,在啟動它時必須設定一個 sentinel.conf 檔案,這個組態檔中必須包含監聽的主節點資訊:

sentinel monitor master-name ip port quorum

其中:

  • master-name 表示給監視的主節點起一個名稱;
  • ip 表示主節點的 IP;
  • port 表示主節點的埠;
  • quorum 表示確認主節點下線的 Sentinel 數量,如果 quorum 設定為 1 表示只要有一臺 Sentinel 判斷它下線了,就可以確認它真的下線了。

如果主節點伺服器 Redis 有密碼,sentinel.conf 必須包含以下內容:

sentinel monitor mymaster 127.0.0.1 6379 1
sentinel auth-pass mymaster pwd654321

啟動 Sentinel 叢集

生產環境我們不會只啟動一臺 Sentinel,因為如果啟動一臺 Sentinel 假如它不幸宕機的話,就不能提供自動容災的服務了,不符合我們高可用的宗旨,所以我們會在不同的物理機上啟動多個 Sentinel 來組成 Sentinel 叢集,來保證 Redis 服務的高可用。

啟動 Sentinel 叢集的方法很簡單,和上面啟動單臺的方式一樣,我們只需要把多個 Sentinel 監聽到一個主伺服器節點,那麼多個 Sentinel 就會自動發現彼此,並組成一個 Sentinel 叢集。

4.png

一般情況下 Sentinel 叢集的數量取大於 1 的奇數,quorum 的引數就設定為一半加 1,例如 5 就設定為 3,7 就設定為 4。

兩個概念:主觀下線和客觀下線。

Sentinel 叢集中,有一個 Sentinel 認為主伺服器已經下線時,它會將這個主伺服器標記為主觀下線(Subjectively DownSDOWN),然後詢問叢集中的其他 Sentinel,是否也認為該伺服器已下線,當同意主伺服器已下線的 Sentinel 數量達到 quorum 引數所指定的數量時,Sentinel 就會將相應的主伺服器標記為客觀下線(Objectively down,ODOWN),然後開始對其進行故障轉移。

主服務競選規則

新主節點競選優先順序設定

redis.conf 中的 replica-priority 選項來設定競選新主節點的優先順序,它的預設值是 100,它的最大值也是 100,這個值越小它的權重就越高。

新主節點競選規則

新主節點的競選會排除不符合條件的從節點,然後再剩餘的從節點按照優先順序來挑選。

存在以下條件的從節點會被排除:

  • 排除所有已經下線以及長時間沒有回覆心跳檢測的疑似已下線從伺服器;

  • 排除所有長時間沒有與主伺服器通訊,資料狀態過時的從伺服器;

  • 排除所有優先順序(replica-priority)為 0 的伺服器。

符合條件的從節點競選順序:

  • 優先順序最高的從節點將會作為新主節點;

  • 優先順序相等則判斷複製偏移量,偏移量最大的從節點獲勝;

  • 如果以上兩個條件都相同,選擇 Redis 執行時隨機生成 ID 最小那個為新的主伺服器。

舊主節點恢復上線

如果之前的舊主節點恢復上線,會作為從節點執行在主從伺服器模式中。

哨兵工作原理

首先每個 Sentinel 會以每秒鐘 1 次的頻率,向已知的主伺服器、從伺服器和以及其他 Sentinel 範例,傳送一個 PING 命令。

如果最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 所設定的值(預設 30s),那麼這個範例會被 Sentinel 標記為主觀下線。

如果一個主伺服器被標記為主觀下線,那麼正在監視這個主伺服器的所有 Sentinel 節點,要以每秒 1 次的頻率確認主伺服器的確進入了主觀下線狀態。

如果有足夠數量(quorum 設定值)的 Sentinel 在指定的時間範圍內同意這一判斷,那麼這個主伺服器被標記為客觀下線。此時所有的 Sentinel 會按照規則協商自動選出新的主節點。

注意:一個有效的 PING 回覆可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果返回值非以上三種回覆,或者在指定時間內沒有回覆 PING 命令, 那麼 Sentinel 認為伺服器返回的回覆無效(non-valid)。

Sentinel 命令操作

Sentinel 可以監視多臺主節點,而不是隻能監視一臺伺服器。想要監視多臺主節點只需要在組態檔中設定多個 sentinel monitor master-name ip port quorum 即可,我們通過 master-name 來區分不同的主節點。

查詢所有被監控的主伺服器資訊

sentinel masters

查詢某個主節點的資訊

sentinel master master-name

檢視某個主節點的 IP 和埠

sentinel get-master-addr-by-name master-name

查詢從節點的資訊

sentinel replicas mymastersentinel slaves master-name

查詢 Sentinel 叢集中的其他 Sentinel 資訊

sentinel sentinels master-name

檢查可用 Sentinel 的數量

sentinel ckquorum master-name

強制故障轉移

sentinel failover master-name

線上修改設定資訊

Redis 2.8.4 之前如果需要修改 Sentinel 的組態檔,需要重新啟動 Sentinel

Redis 2.8.4 之後,我們可以線上修改組態檔了。

增加監視主節點

sentinel monitor mymaster IP Port Quorum 命令。

移除主節點的監視

使用 sentinel remove master-name 命令。

修改 quorum 引數

使用 sentinel set master-name quorum n 命令。

quorum 引數用來表示確認主節點下線的 Sentinel 數量,如果 quorum 設定為 1 表示只要有一臺 Sentinel 確認主觀下線後,這個主節點就客觀(真正地)下線了。

以上所有對組態檔的修改,都會自動被重新整理到物理組態檔 sentinel.conf

程式碼實戰

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import utils.Config;

import java.util.HashSet;
import java.util.Set;

public class SentinelExample {
    // master name
    private static String _MASTER_NAME = "mymaster";

    public static void main(String[] args) {
        // Sentinel 設定資訊
        Set<String> set = new HashSet<>();
        // 連線資訊 ip:port
        set.add("127.0.0.1:26379");
        // 建立 Sentinel 連線池
        JedisSentinelPool jedisSentinel = new JedisSentinelPool(_MASTER_NAME,
                set, Config.REDIS_AUTH);
        // 獲取 Redis 使用者端
        Jedis jedis = jedisSentinel.getResource();
        // 設定元素
        String setRes = jedis.set("key", "Hello, redis.");
        System.out.println(setRes);
        // 獲取元素
        System.out.println(jedis.get("key"));
    }
}

更多程式設計相關知識,請存取:!!

以上就是聊聊Redis中的主從同步和哨兵模式的詳細內容,更多請關注TW511.COM其它相關文章!