首頁 > 資料庫 > Redis > 主體

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

青灯夜游
發布: 2022-02-16 10:59:57
轉載
3542 人瀏覽過

這篇文章帶大家深入了解Redis中的主從同步和哨兵模式,介紹一下開啟關閉主從同步、搭建啟動Sentinel的方法,希望對大家有所幫助!

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

主從同步

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

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

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

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

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

##主從同步的優點

主從同步有以下三個優點

  • 效能面向:有了主從同步之後,可以把查詢任務分配給從伺服器用主伺服器來執行寫入操作,這樣極大的提高了程式運行的效率,把所有壓力分攤到各個伺服器了;
  • 高可用:當有了主從同步之後,當主伺服器節點宕機之後,可以很迅速的把從節點提升為主節點,為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 的最小分配單位是一主一從。

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

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 叢集。

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

一般情況下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中的主從同步和哨兵模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板