這篇文章帶大家深入了解Redis中的主從同步和哨兵模式,介紹一下開啟關閉主從同步、搭建啟動Sentinel的方法,希望對大家有所幫助!
主從同步(主從複製)是Redis
高可用服務的基石,也是多機運作中最基礎的一個。 【相關推薦:Redis影片教學】
我們把主要儲存資料的節點叫做主節點(master
),把其他透過複製主節點資料的複本節點叫做從節點(slave
),如下圖所示:
#在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 的最佳化方法是當從服務離線之後,主伺服器會把離線之後的寫入指令,儲存在特定大小的佇列中,佇列是可以保證先進先出的執行順序的,當從伺服器重寫恢復上線之後,主服務會判斷離線這段時間內的命令是否還在佇列中,如果在就直接把佇列中的資料傳送給從伺服器,這樣就避免了完整同步的資源浪費。
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 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
叢集。
一般情況下Sentinel
叢集的數量取大於1 的奇數,quorum
的參數設定為一半加1,例如5 就設定為3,7 就設定為4。
兩個概念:主觀下線和客觀下線。
當Sentinel
叢集中,有一個Sentinel
認為主伺服器已經下線時,它會將這個主伺服器標記為主觀下線(Subjectively Down
,SDOWN
),然後詢問叢集中的其他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 mymaster
或sentinel 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中文網其他相關文章!