本篇內(nèi)容主要講解“redis中的主從同步和哨兵模式是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Redis中的主從同步和哨兵模式是什么”吧!
站在用戶的角度思考問題,與客戶深入溝通,找到興縣網(wǎng)站設(shè)計(jì)與興縣網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋興縣地區(qū)。
主從同步(主從復(fù)制)是 Redis
高可用服務(wù)的基石,也是多機(jī)運(yùn)行中最基礎(chǔ)的一個(gè)。
我們把主要存儲(chǔ)數(shù)據(jù)的節(jié)點(diǎn)叫做主節(jié)點(diǎn) (master
),把其他通過復(fù)制主節(jié)點(diǎn)數(shù)據(jù)的副本節(jié)點(diǎn)叫做從節(jié)點(diǎn) (slave
),如下圖所示:
在 Redis
中一個(gè)主節(jié)點(diǎn)可以擁有多個(gè)從節(jié)點(diǎn),一個(gè)從節(jié)點(diǎn)也可以是其他服務(wù)器的主節(jié)點(diǎn),如下圖所示:
主從同步的優(yōu)點(diǎn)
主從同步具有以下三個(gè)優(yōu)點(diǎn):
性能方面:有了主從同步之后,可以把查詢?nèi)蝿?wù)分配給從服務(wù)器,用主服務(wù)器來執(zhí)行寫操作,這樣極大的提高了程序運(yùn)行的效率,把所有壓力分?jǐn)偟礁鱾€(gè)服務(wù)器了;
高可用:當(dāng)有了主從同步之后,當(dāng)主服務(wù)器節(jié)點(diǎn)宕機(jī)之后,可以很迅速的把從節(jié)點(diǎn)提升為主節(jié)點(diǎn),為 Redis
服務(wù)器的宕機(jī)恢復(fù)節(jié)省了寶貴的時(shí)間;
防止數(shù)據(jù)丟失:當(dāng)主服務(wù)器磁盤壞掉之后,其他從服務(wù)器還保留著相關(guān)的數(shù)據(jù),不至于數(shù)據(jù)全部丟失。
開啟主從同步
運(yùn)行中設(shè)置從服務(wù)器
在 Redis
運(yùn)行過程中,我們可以使用 replicaof host port
命令,把自己設(shè)置為目標(biāo) IP
的從服務(wù)器。
如果主服務(wù)設(shè)置了密碼,需要在從服務(wù)器輸入主服務(wù)器的密碼,使用 config set masterauth 主服務(wù)密碼
命令的方式
在執(zhí)行完 replicaof
命令之后,從服務(wù)器的數(shù)據(jù)會(huì)被清空,主服務(wù)會(huì)把它的數(shù)據(jù)副本同步給從服務(wù)器。
啟動(dòng)時(shí)設(shè)置從服務(wù)器
可以使用命令 redis-server --port 6380 --replicaof 127.0.0.1 6379
將自己設(shè)置成目標(biāo)服務(wù)器的從服務(wù)器。
數(shù)據(jù)同步
完整數(shù)據(jù)同步
當(dāng)有新的從服務(wù)器連接時(shí),為了保障多個(gè)數(shù)據(jù)庫的一致性,主服務(wù)器會(huì)執(zhí)行一次 bgsave
命令生成一個(gè) RDB
文件,然后再以 Socket
的方式發(fā)送給從服務(wù)器,從服務(wù)器收到 RDB
文件之后再把所有的數(shù)據(jù)加載到自己的程序中,就完成了一次全量的數(shù)據(jù)同步。
部分?jǐn)?shù)據(jù)同步
在 Redis 2.8
之前每次從服務(wù)器離線再重新上線之前,主服務(wù)器會(huì)進(jìn)行一次完整的數(shù)據(jù)同步,然后這種情況如果發(fā)生在離線時(shí)間比較短的情況下,只有少量的數(shù)據(jù)不同步卻要同步所有的數(shù)據(jù)是非常笨拙和不劃算的,在 Redis 2.8
這個(gè)功能得到了優(yōu)化。
Redis 2.8
的優(yōu)化方法是當(dāng)從服務(wù)離線之后,主服務(wù)器會(huì)把離線之后的寫入命令,存儲(chǔ)在一個(gè)特定大小的隊(duì)列中,隊(duì)列是可以保證先進(jìn)先出的執(zhí)行順序的,當(dāng)從服務(wù)器重寫恢復(fù)上線之后,主服務(wù)會(huì)判斷離線這段時(shí)間內(nèi)的命令是否還在隊(duì)列中,如果在就直接把隊(duì)列中的數(shù)據(jù)發(fā)送給從服務(wù)器,這樣就避免了完整同步的資源浪費(fèi)。
存儲(chǔ)離線命令的隊(duì)列大小默認(rèn)是 1MB,使用者可以自行修改隊(duì)列大小的配置項(xiàng) repl-backlog-size
。
無盤數(shù)據(jù)同步
在第一次主從連接的時(shí)候,會(huì)先產(chǎn)生一個(gè) RDB
文件,再把 RDB
文件發(fā)送給從服務(wù)器,如果主服務(wù)器是非固態(tài)硬盤的時(shí)候,系統(tǒng)的 I/O
操作是非常高的。
Redis 2.8.18
新增了無盤復(fù)制功能,無盤復(fù)制功能不會(huì)在本地創(chuàng)建 RDB
文件,而是會(huì)派生出一個(gè)子進(jìn)程,然后由子進(jìn)程通過 Socket
的方式,直接將 RDB
文件寫入到從服務(wù)器,這樣主服務(wù)器就可以在不創(chuàng)建 RDB
文件的情況下,完成與從服務(wù)器的數(shù)據(jù)同步。
要使用無須復(fù)制功能,只需把配置項(xiàng) repl-diskless-sync
的值設(shè)置為 yes
即可,它默認(rèn)配置值為 no
。
查詢服務(wù)器的角色
使用 role
命令,來查詢當(dāng)前服務(wù)器的主從角色信息。
關(guān)閉主從同步
可以使用 replicaof no one
命令來停止從服務(wù)器的復(fù)制。
執(zhí)行了 replicaof no one
命令之后,自己就從服務(wù)器變成主服務(wù)器了。
服務(wù)器類型的轉(zhuǎn)換并不會(huì)影響數(shù)據(jù),這臺(tái)服務(wù)器的數(shù)據(jù)將會(huì)被保留。
注意事項(xiàng)
數(shù)據(jù)一致性問題
當(dāng)從服務(wù)器已經(jīng)完成和主服務(wù)的數(shù)據(jù)同步之后,再新增的命令會(huì)以異步的方式發(fā)送至從服務(wù)器,在這個(gè)過程中主從同步會(huì)有短暫的數(shù)據(jù)不一致,如在這個(gè)異步同步發(fā)生之前主服務(wù)器宕機(jī)了,會(huì)造成數(shù)據(jù)不一致。
從服務(wù)器只讀性
默認(rèn)情況下,處于復(fù)制模式的主服務(wù)器既可以執(zhí)行寫操作也可以執(zhí)行讀操作,而從服務(wù)器則只能執(zhí)行讀操作。
可以在從服務(wù)器上執(zhí)行 config set replica-read-only no
命令,使從服務(wù)器開啟寫模式,但需要注意以下幾點(diǎn):
在從服務(wù)器上寫的數(shù)據(jù)不會(huì)同步到主服務(wù)器;
當(dāng)鍵值相同時(shí)主服務(wù)器上的數(shù)據(jù)可以覆蓋從服務(wù)器;
在進(jìn)行完整數(shù)據(jù)同步時(shí),從服務(wù)器數(shù)據(jù)會(huì)被清空。
復(fù)制命令的變化
Redis 5.0
之前使用的復(fù)制命令是 slaveof
,在 Redis 5.0
之后復(fù)制命令才被改為 replicaof
,在高版本(Redis 5+
)中我們應(yīng)該盡量使用 replicaof
,因?yàn)?slaveof
命令可能會(huì)被隨時(shí)廢棄掉。
主從復(fù)制模式,它是屬于
Redis
多機(jī)運(yùn)行的基礎(chǔ),但這種模式本身存在一個(gè)致命的問題,當(dāng)主節(jié)點(diǎn)奔潰之后,需要人工干預(yù)才能恢復(fù)Redis
的正常使用。我們需要一個(gè)自動(dòng)的工具——
Redis Sentinel
(哨兵模式)來把手動(dòng)的過程變成自動(dòng)的,讓Redis
擁有自動(dòng)容災(zāi)恢復(fù)(failover
)的能力。哨兵就相當(dāng)于對(duì)主從服務(wù)器做一個(gè)監(jiān)視的任務(wù)。一旦發(fā)現(xiàn)主服務(wù)器宕機(jī)了,就迅速啟動(dòng)相應(yīng)的規(guī)則將某一臺(tái)從服務(wù)器升級(jí)為主服務(wù)器,無需人工干預(yù),更穩(wěn)定更快。
Redis Sentinel
的最小分配單位是一主一從。
Redis Sentinel 搭建
使用命令 ./src/redis-sentinel sentinel.conf
來啟動(dòng) Sentinel
,在啟動(dòng)它時(shí)必須設(shè)置一個(gè) sentinel.conf
文件,這個(gè)配置文件中必須包含監(jiān)聽的主節(jié)點(diǎn)信息:
sentinel monitor master-name ip port quorum
其中:
master-name
表示給監(jiān)視的主節(jié)點(diǎn)起一個(gè)名稱;
ip
表示主節(jié)點(diǎn)的 IP;
port
表示主節(jié)點(diǎn)的端口;
quorum
表示確認(rèn)主節(jié)點(diǎn)下線的 Sentinel
數(shù)量,如果 quorum
設(shè)置為 1 表示只要有一臺(tái) Sentinel
判斷它下線了,就可以確認(rèn)它真的下線了。
如果主節(jié)點(diǎn)服務(wù)器 Redis
有密碼,sentinel.conf
必須包含以下內(nèi)容:
sentinel monitor mymaster 127.0.0.1 6379 1 sentinel auth-pass mymaster pwd654321
啟動(dòng) Sentinel 集群
生產(chǎn)環(huán)境我們不會(huì)只啟動(dòng)一臺(tái) Sentinel
,因?yàn)槿绻麊?dòng)一臺(tái) Sentinel
假如它不幸宕機(jī)的話,就不能提供自動(dòng)容災(zāi)的服務(wù)了,不符合我們高可用的宗旨,所以我們會(huì)在不同的物理機(jī)上啟動(dòng)多個(gè) Sentinel
來組成 Sentinel
集群,來保證 Redis
服務(wù)的高可用。
啟動(dòng) Sentinel
集群的方法很簡(jiǎn)單,和上面啟動(dòng)單臺(tái)的方式一樣,我們只需要把多個(gè) Sentinel
監(jiān)聽到一個(gè)主服務(wù)器節(jié)點(diǎn),那么多個(gè) Sentinel
就會(huì)自動(dòng)發(fā)現(xiàn)彼此,并組成一個(gè) Sentinel
集群。
一般情況下 Sentinel
集群的數(shù)量取大于 1 的奇數(shù),quorum
的參數(shù)就設(shè)置為一半加 1,例如 5 就設(shè)置為 3,7 就設(shè)置為 4。
兩個(gè)概念:主觀下線和客觀下線。
當(dāng) Sentinel
集群中,有一個(gè) Sentinel
認(rèn)為主服務(wù)器已經(jīng)下線時(shí),它會(huì)將這個(gè)主服務(wù)器標(biāo)記為主觀下線(Subjectively Down
,SDOWN
),然后詢問集群中的其他 Sentinel
,是否也認(rèn)為該服務(wù)器已下線,當(dāng)同意主服務(wù)器已下線的 Sentinel
數(shù)量達(dá)到 quorum
參數(shù)所指定的數(shù)量時(shí),Sentinel
就會(huì)將相應(yīng)的主服務(wù)器標(biāo)記為客觀下線(Objectively down,ODOWN
),然后開始對(duì)其進(jìn)行故障轉(zhuǎn)移。
主服務(wù)競(jìng)選規(guī)則
新主節(jié)點(diǎn)競(jìng)選優(yōu)先級(jí)設(shè)置
redis.conf
中的 replica-priority
選項(xiàng)來設(shè)置競(jìng)選新主節(jié)點(diǎn)的優(yōu)先級(jí),它的默認(rèn)值是 100,它的最大值也是 100,這個(gè)值越小它的權(quán)重就越高。
新主節(jié)點(diǎn)競(jìng)選規(guī)則
新主節(jié)點(diǎn)的競(jìng)選會(huì)排除不符合條件的從節(jié)點(diǎn),然后再剩余的從節(jié)點(diǎn)按照優(yōu)先級(jí)來挑選。
存在以下條件的從節(jié)點(diǎn)會(huì)被排除:
排除所有已經(jīng)下線以及長(zhǎng)時(shí)間沒有回復(fù)心跳檢測(cè)的疑似已下線從服務(wù)器;
排除所有長(zhǎng)時(shí)間沒有與主服務(wù)器通信,數(shù)據(jù)狀態(tài)過時(shí)的從服務(wù)器;
排除所有優(yōu)先級(jí)(replica-priority
)為 0 的服務(wù)器。
符合條件的從節(jié)點(diǎn)競(jìng)選順序:
優(yōu)先級(jí)最高的從節(jié)點(diǎn)將會(huì)作為新主節(jié)點(diǎn);
優(yōu)先級(jí)相等則判斷復(fù)制偏移量,偏移量最大的從節(jié)點(diǎn)獲勝;
如果以上兩個(gè)條件都相同,選擇 Redis
運(yùn)行時(shí)隨機(jī)生成 ID 最小那個(gè)為新的主服務(wù)器。
舊主節(jié)點(diǎn)恢復(fù)上線
如果之前的舊主節(jié)點(diǎn)恢復(fù)上線,會(huì)作為從節(jié)點(diǎn)運(yùn)行在主從服務(wù)器模式中。
哨兵工作原理
首先每個(gè) Sentinel
會(huì)以每秒鐘 1 次的頻率,向已知的主服務(wù)器、從服務(wù)器和以及其他 Sentinel
實(shí)例,發(fā)送一個(gè) PING 命令。
如果最后一次有效回復(fù) PING
命令的時(shí)間超過 down-after-milliseconds
所配置的值(默認(rèn) 30s),那么這個(gè)實(shí)例會(huì)被 Sentinel
標(biāo)記為主觀下線。
如果一個(gè)主服務(wù)器被標(biāo)記為主觀下線,那么正在監(jiān)視這個(gè)主服務(wù)器的所有 Sentinel
節(jié)點(diǎn),要以每秒 1 次的頻率確認(rèn)主服務(wù)器的確進(jìn)入了主觀下線狀態(tài)。
如果有足夠數(shù)量(quorum
配置值)的 Sentinel
在指定的時(shí)間范圍內(nèi)同意這一判斷,那么這個(gè)主服務(wù)器被標(biāo)記為客觀下線。此時(shí)所有的 Sentinel
會(huì)按照規(guī)則協(xié)商自動(dòng)選出新的主節(jié)點(diǎn)。
注意:一個(gè)有效的 PING
回復(fù)可以是:+PONG、-LOADING
或者 -MASTERDOWN
。如果返回值非以上三種回復(fù),或者在指定時(shí)間內(nèi)沒有回復(fù) PING
命令, 那么 Sentinel
認(rèn)為服務(wù)器返回的回復(fù)無效(non-valid
)。
Sentinel 命令操作
Sentinel 可以監(jiān)視多臺(tái)主節(jié)點(diǎn),而不是只能監(jiān)視一臺(tái)服務(wù)器。想要監(jiān)視多臺(tái)主節(jié)點(diǎn)只需要在配置文件中設(shè)置多個(gè) sentinel monitor master-name ip port quorum
即可,我們通過 master-name
來區(qū)分不同的主節(jié)點(diǎn)。
查詢所有被監(jiān)控的主服務(wù)器信息
sentinel masters
查詢某個(gè)主節(jié)點(diǎn)的信息
sentinel master master-name
查看某個(gè)主節(jié)點(diǎn)的 IP 和端口
sentinel get-master-addr-by-name master-name
查詢從節(jié)點(diǎn)的信息
sentinel replicas mymaster
或 sentinel slaves master-name
查詢 Sentinel 集群中的其他 Sentinel 信息
sentinel sentinels master-name
檢查可用 Sentinel 的數(shù)量
sentinel ckquorum master-name
強(qiáng)制故障轉(zhuǎn)移
sentinel failover master-name
在線修改配置信息
在 Redis 2.8.4
之前如果需要修改 Sentinel
的配置文件,需要重啟 Sentinel
。
Redis 2.8.4
之后,我們可以在線修改配置文件了。
增加監(jiān)視主節(jié)點(diǎn)
sentinel monitor mymaster IP Port Quorum
命令。
移除主節(jié)點(diǎn)的監(jiān)視
使用 sentinel remove master-name
命令。
修改 quorum 參數(shù)
使用 sentinel set master-name quorum n
命令。
quorum
參數(shù)用來表示確認(rèn)主節(jié)點(diǎn)下線的 Sentinel
數(shù)量,如果 quorum
設(shè)置為 1 表示只要有一臺(tái) Sentinel 確認(rèn)主觀下線后,這個(gè)主節(jié)點(diǎn)就客觀(真正地)下線了。
以上所有對(duì)配置文件的修改,都會(huì)自動(dòng)被刷新到物理配置文件
sentinel.conf
中
代碼實(shí)戰(zhàn)
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 配置信息 Setset = new HashSet<>(); // 連接信息 ip:port set.add("127.0.0.1:26379"); // 創(chuàng)建 Sentinel 連接池 JedisSentinelPool jedisSentinel = new JedisSentinelPool(_MASTER_NAME, set, Config.REDIS_AUTH); // 獲取 Redis 客戶端 Jedis jedis = jedisSentinel.getResource(); // 設(shè)置元素 String setRes = jedis.set("key", "Hello, redis."); System.out.println(setRes); // 獲取元素 System.out.println(jedis.get("key")); } }
到此,相信大家對(duì)“Redis中的主從同步和哨兵模式是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!