共計 5448 個字符,預計需要花費 14 分鐘才能閱讀完成。
本篇內容主要講解“Redis 中的主從同步和哨兵模式是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“Redis 中的主從同步和哨兵模式是什么”吧!
主從同步
主從同步(主從復制)是 Redis 高可用服務的基石,也是多機運行中最基礎的一個。
我們把主要存儲數據的節點叫做主節點 (master),把其他通過復制主節點數據的副本節點叫做從節點 (slave),如下圖所示:
在 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 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 中的主從同步和哨兵模式是什么”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!