通過Docker部署Redis 6.x集群的方法
系統(tǒng)環(huán)境:
- Redis 版本:6.0.8
- Docker 版本:19.03.12
- 系統(tǒng)版本:CoreOS 7.8
- 內(nèi)核版本:5.8.5-1.el7.elrepo.x86_64
一、什么是 Redis 集群模式
在 Redis 3.0 版本后正式推出 Redis 集群模式,該模式是 Redis 的分布式的解決方案,是一個(gè)提供在多個(gè) Redis 節(jié)點(diǎn)間共享數(shù)據(jù)的程序集,且 Redis 集群是去中心化的,它的每個(gè) Master 節(jié)點(diǎn)都可以進(jìn)行讀寫數(shù)據(jù),每個(gè)節(jié)點(diǎn)都擁有平等的關(guān)系,每個(gè)節(jié)點(diǎn)都保持各自的數(shù)據(jù)和整個(gè)集群的狀態(tài)。
Redis 集群設(shè)計(jì)的主要目的是讓 Redis 數(shù)據(jù)存儲(chǔ)能夠線性擴(kuò)展,通過分區(qū)來提供一定程度的可用性,在實(shí)際環(huán)境中當(dāng)某個(gè)節(jié)點(diǎn)宕機(jī)或者不可達(dá)的情況下其可以繼續(xù)處理命令。但是,如果發(fā)生較大故障(例如,大多數(shù)主站不可用時(shí))時(shí)集群會(huì)停止運(yùn)行,即 redis 集群不能保證數(shù)據(jù)的強(qiáng)一致性。
二、為什么需要 Redis 集群
- 高可用性:Redis 在集群模式下每個(gè) Master 都是主從復(fù)制模式,其 Master 節(jié)點(diǎn)上的數(shù)據(jù)會(huì)實(shí)時(shí)同步到 Slave 節(jié)點(diǎn)上,當(dāng) Master 節(jié)點(diǎn)不可用時(shí),其對(duì)應(yīng)的 Slave 節(jié)點(diǎn)身份會(huì)更改為 Master 節(jié)點(diǎn),保證集群的可用性。
- 數(shù)據(jù)橫向擴(kuò)展:Redis 是一個(gè)內(nèi)存數(shù)據(jù)庫,所有數(shù)據(jù)都存在內(nèi)存中,在單節(jié)點(diǎn)中所在服務(wù)器能給與的內(nèi)存是有一定限制。當(dāng)數(shù)據(jù)量達(dá)到一定程度后,內(nèi)存將不足以支撐這么多的數(shù)據(jù)存儲(chǔ),這時(shí)候需要將數(shù)據(jù)進(jìn)行分片存儲(chǔ),而 Redis 集群模式就是將數(shù)據(jù)分片存儲(chǔ),非常方便橫向擴(kuò)展。
三、Redis 集群的數(shù)據(jù)分片
Redis 集群沒有使用一致性 Hash, 而是引入了”哈希槽”的概念。Redis 集群有 16384 個(gè)哈希槽,每個(gè) key 通過 CRC16 校驗(yàn)后對(duì) 16384 取模來決定放置哪個(gè)槽,集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分 hash 槽。
舉個(gè)例子,比如當(dāng)前集群有3個(gè)節(jié)點(diǎn),那么:
- 節(jié)點(diǎn) A 包含 0 到 5460 號(hào)哈希槽;
- 節(jié)點(diǎn) B 包含 5461 到 10922 號(hào)哈希槽;
- 節(jié)點(diǎn) C 包含 10923 到 16383 號(hào)哈希槽;
這種結(jié)構(gòu)很容易”添加”或者”刪除”節(jié)點(diǎn). 比如如果我想新添加個(gè)節(jié)點(diǎn) D,我需要從節(jié)點(diǎn) A, B, C 中得部分槽轉(zhuǎn)移到節(jié)點(diǎn) D 上, 如果我想移除節(jié)點(diǎn) A,則需要將 A 中的槽移到 B 和 C 節(jié)點(diǎn)上,然后將沒有任何槽的 A 節(jié)點(diǎn)從集群中移除即可。由于從一個(gè)節(jié)點(diǎn)將哈希槽移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì)停止服務(wù),所以無論添加刪除或者改變某個(gè)節(jié)點(diǎn)的哈希槽的數(shù)量都不會(huì)造成集群不可用的狀態(tài)。
Redis 支持多個(gè) key 操作,只要這些 key 在一個(gè)單個(gè)命令中執(zhí)行(或者一個(gè)事務(wù),或者 Lua 腳本執(zhí)行),那么它們就屬于相同的 Hash 槽。你也可以用 hash tags 命令強(qiáng)制多個(gè) key 都在相同的 hash 槽中。
四、Redis 集群的主從復(fù)制
集群中的主從模型
在 Redis 集群模式下,為了防止集群部分節(jié)點(diǎn)因宕機(jī)等情況造成不可用,故而 Redis 集群使用了主從復(fù)制模式。在該模式下要求 Redis 集群至少要存在六個(gè)節(jié)點(diǎn),其中三個(gè)節(jié)點(diǎn)為主節(jié)點(diǎn),能夠?qū)ν馓峁┳x寫。還有三個(gè)節(jié)點(diǎn)為從節(jié)點(diǎn),會(huì)同步其對(duì)應(yīng)的主節(jié)點(diǎn)的數(shù)據(jù)。當(dāng)某個(gè)主節(jié)點(diǎn)出現(xiàn)問題不可用時(shí),Redis 將通過選舉算法從主節(jié)點(diǎn)對(duì)應(yīng)的從節(jié)點(diǎn)中選擇一個(gè)節(jié)點(diǎn)(主節(jié)點(diǎn)存在多個(gè)從節(jié)點(diǎn)的情況下),將其更改為一個(gè)新的主節(jié)點(diǎn),且能夠?qū)ν馓峁┓?wù)。
例如,在存在 A,B,C 三個(gè)主節(jié)點(diǎn)和其對(duì)應(yīng)的 (A1、A2),(B1、B2),(C1、C2) 六個(gè)從節(jié)點(diǎn),共九個(gè)節(jié)點(diǎn)中,如果節(jié)點(diǎn) A 節(jié)點(diǎn)掛掉,那么其對(duì)應(yīng)的從節(jié)點(diǎn) A1、A2 節(jié)點(diǎn)將通過選舉算法,選擇其中一個(gè)節(jié)點(diǎn)提升為主節(jié)點(diǎn),以確保集群能夠正常服務(wù)。不過當(dāng) A1、A2 兩個(gè)從節(jié)點(diǎn)或者或者半數(shù)以上主節(jié)點(diǎn)不可用時(shí),那么集群也是不可用的。
在部署 Redis 集群模式時(shí),至少需要六個(gè)節(jié)點(diǎn)組成集群才能保證集群的可用性。
主從復(fù)制的相關(guān)概念
(1)、全量復(fù)制與增量復(fù)制
在 Redis 主從復(fù)制中,分為”全量復(fù)制”和”增量復(fù)制”兩種數(shù)據(jù)同步方式:
- 全量復(fù)制:用于初次復(fù)制或其它無法進(jìn)行部分復(fù)制的情況,將主節(jié)點(diǎn)中的所有數(shù)據(jù)都發(fā)送給從節(jié)點(diǎn)。當(dāng)數(shù)據(jù)量過大的時(shí)候,會(huì)造成很大的網(wǎng)絡(luò)開銷。
- 增量復(fù)制:用于處理在主從復(fù)制中因網(wǎng)絡(luò)閃退等原因造成數(shù)據(jù)丟失場景,當(dāng)從節(jié)點(diǎn)再次連上主節(jié)點(diǎn),如果條件允許,主節(jié)點(diǎn)會(huì)補(bǔ)發(fā)丟失數(shù)據(jù)給從節(jié)點(diǎn),因?yàn)檠a(bǔ)發(fā)的數(shù)據(jù)遠(yuǎn)遠(yuǎn)小于全量數(shù)據(jù),可以有效避免全量復(fù)制的過高開銷。但需要注意,如果網(wǎng)絡(luò)中斷時(shí)間過長,造成主節(jié)點(diǎn)沒有能夠完整地保存中斷期間執(zhí)行的寫命令,則無法進(jìn)行部分復(fù)制,仍使用全量復(fù)制。
(2)、記錄復(fù)制位置的偏移量
- 參與復(fù)制的主從節(jié)點(diǎn)都會(huì)維護(hù)自身復(fù)制偏移量,主節(jié)點(diǎn)在處理完寫入命令操作后,會(huì)把命令的字節(jié)長度做累加記錄,可以使用
info replication
命令查詢master_repl_offset
偏移量信息。 - 從節(jié)點(diǎn)每秒鐘上報(bào)自身的復(fù)制偏移量給主節(jié)點(diǎn),因此主節(jié)點(diǎn)也會(huì)保存從節(jié)點(diǎn)的復(fù)制偏移量。
- 從節(jié)點(diǎn)在接收到主節(jié)點(diǎn)發(fā)送的命令后,也會(huì)累加記錄自身的偏移量,可以使用
info replication
命令查詢slave_repl_offset
偏移量信息。
(3)、復(fù)制積壓緩沖區(qū)
復(fù)制積壓緩沖區(qū)(backlog)是保存在主節(jié)點(diǎn)上的一個(gè)固定長度的隊(duì)列,默認(rèn)大小為 1MB,當(dāng)主節(jié)點(diǎn)有連接的從節(jié)點(diǎn)時(shí)被創(chuàng)建,這時(shí)主節(jié)點(diǎn)響應(yīng)寫命令時(shí),不但會(huì)把命令發(fā)給從節(jié)點(diǎn),還會(huì)寫入復(fù)制積壓緩沖區(qū),作為寫命令的備份。
除了存儲(chǔ)寫命令,復(fù)制積壓緩沖區(qū)中還存儲(chǔ)了其中的每個(gè)字節(jié)對(duì)應(yīng)的復(fù)制偏移量(offset) 。由于復(fù)制積壓緩沖區(qū)定長且先進(jìn)先出,所以它保存的是主節(jié)點(diǎn)最近執(zhí)行的寫命令,時(shí)間較早的寫命令會(huì)被擠出緩沖區(qū)。
(4)、節(jié)點(diǎn)運(yùn)行的 ID
- 每個(gè) Redis 節(jié)點(diǎn)啟動(dòng)后都會(huì)動(dòng)態(tài)分配一個(gè) 40 位的十六進(jìn)制字符串為運(yùn)行 ID。運(yùn)行 ID 的主要作用是來唯一識(shí)別 Redis 節(jié)點(diǎn),比如,從節(jié)點(diǎn)保存主節(jié)點(diǎn)的運(yùn)行 ID 識(shí)別自已正在復(fù)制是哪個(gè)主節(jié)點(diǎn)。如果只使用 IP + Port 的方式識(shí)別主節(jié)點(diǎn),那么主節(jié)點(diǎn)重啟變更了整體數(shù)據(jù)集(如替換 RDB/AOF 文件),從節(jié)點(diǎn)再基于偏移量復(fù)制數(shù)據(jù)將是不安全的,因此當(dāng)運(yùn)行 ID 變化后從節(jié)點(diǎn)將做全量復(fù)制??梢栽?info server 命令查看當(dāng)前節(jié)點(diǎn)的運(yùn)行 ID。
- 需要注意的是 Redis 關(guān)閉再啟動(dòng),運(yùn)行的 ID 會(huì)隨之變化。
主從復(fù)制的執(zhí)行過程
(1)、psync 命令
從節(jié)點(diǎn)使用 psync 從主節(jié)點(diǎn)獲取 runid 與 offset。
主節(jié)點(diǎn)會(huì)根據(jù)自身情況返回響應(yīng)信息,可能是 FULLRESYNC runid offset 觸發(fā)全量復(fù)制,可能是 CONTINUE 觸發(fā)增量復(fù)制。
(2)、psync 觸發(fā)全量復(fù)制
從節(jié)點(diǎn)使用 psync 命令完成部分復(fù)制和全量復(fù)制功能:
當(dāng)從節(jié)點(diǎn)第一次連接主節(jié)點(diǎn)時(shí)候,執(zhí)行全量復(fù)制:
① Slave 節(jié)點(diǎn)發(fā)送 psync? - 1 命令,表示要求 Master 執(zhí)行數(shù)據(jù)同步;
② Master 檢測到?jīng)]有 offset ,是第一次執(zhí)行復(fù)制,執(zhí)行全量復(fù)制,就發(fā)送 FULLRESYNC {runid} {offset} 命令,將 runid 和 offset 發(fā)送到 slave 節(jié)點(diǎn)。
③ Slave 節(jié)點(diǎn)保存 Master 節(jié)點(diǎn)傳遞的 runid 與 offset 信息。
④ Master 節(jié)點(diǎn)執(zhí)行 bgsave 生成 RBD 快照文件,并使用緩沖區(qū)記錄從現(xiàn)在開始執(zhí)行的全部命令。
⑤ Master 節(jié)點(diǎn)發(fā)送 RBD 文件到 Slave 節(jié)點(diǎn)。
⑥ Master 節(jié)點(diǎn)發(fā)送 BUFFER 緩存區(qū)記錄的寫命令到 Slave 節(jié)點(diǎn)。
⑦ Slave 節(jié)點(diǎn)清空舊數(shù)據(jù)。
⑧ Slave 節(jié)點(diǎn)載入 Master 節(jié)點(diǎn)傳入的 RBD 文件。
(2)、psync 觸發(fā)增量復(fù)制
當(dāng)從節(jié)點(diǎn)與主節(jié)點(diǎn)發(fā)送中斷后,從節(jié)點(diǎn)會(huì)重新連接主節(jié)點(diǎn),這時(shí)會(huì)觸發(fā)增量復(fù)制,過程如下:
① Slave 節(jié)點(diǎn)使用 psync 發(fā)送 runid 和 offset 值。
② Master 節(jié)點(diǎn)驗(yàn)證 Slave 節(jié)點(diǎn)發(fā)送的 runid 是否和自己相同:
- 不相同:不相同則執(zhí)行全量復(fù)制;
- 相同:則還需要驗(yàn)證緩存區(qū)中是否存在對(duì)應(yīng)的 offset,如果不存在就執(zhí)行全量復(fù)制,否則執(zhí)行增量復(fù)制;
③ 滿足存在對(duì)應(yīng) offset 這個(gè)條件后,則驗(yàn)證緩存區(qū)中的 offset 值是否和 Slave 節(jié)點(diǎn)發(fā)送的 offset 相同:
- 相同:返回 offset 值相同,不進(jìn)行復(fù)制操作;
- 不相同:發(fā)送 CONTINUE offset 命令(注意:這里的 offset 是 Master 節(jié)點(diǎn)緩存區(qū)記錄的 offset 值,不是 Slave 節(jié)點(diǎn)傳遞的 offset 值);
④ Master 節(jié)點(diǎn)從復(fù)制緩存區(qū)拷貝數(shù)據(jù),從 Slave 節(jié)點(diǎn)發(fā)送的 offset 開始,到 Master 節(jié)點(diǎn)緩存區(qū)記錄的 offset 結(jié)束,將這個(gè)范圍內(nèi)的數(shù)據(jù)給 Slave 節(jié)點(diǎn)。
五、Redis 集群相關(guān)概念
Redis 集群中的一致性
Redis 在官方文檔中提及,其并不能保證數(shù)據(jù)的強(qiáng)一致性,即 Redis 集群在特定的條件下寫入的數(shù)據(jù)可能會(huì)丟失,主要原因是因?yàn)?Redis 集群使用了異步復(fù)制模式,其寫入的操作過程如下:
執(zhí)行順序如下:
① 客戶端向任意一臺(tái)主節(jié)點(diǎn)寫入一條命令;
② 主節(jié)點(diǎn)對(duì)向客戶端回復(fù)命令執(zhí)行的狀態(tài);
③ 主節(jié)點(diǎn)將寫操作命令傳遞給他的從節(jié)點(diǎn);
Redis 集群對(duì)性能和一致性之間做出權(quán)衡,設(shè)置主節(jié)點(diǎn)在接收到客戶端寫命令后再將執(zhí)行的命令發(fā)送到各個(gè)從節(jié)點(diǎn)進(jìn)行同步,這個(gè)過程是異步操作,且主節(jié)點(diǎn)不會(huì)等待從節(jié)點(diǎn)回復(fù)信息就立即回復(fù)客戶端命令的執(zhí)行狀態(tài)。這樣減少同步操作,可以很大提高系統(tǒng)的執(zhí)行速度,避免等待從節(jié)點(diǎn)回復(fù)消息這個(gè)過程成為系統(tǒng)性能的瓶頸。
然而,因?yàn)橹鞴?jié)點(diǎn)不等待從節(jié)點(diǎn)收到信息后進(jìn)行回復(fù),就將命令的執(zhí)行狀態(tài)回復(fù)給了客戶端,那么在節(jié)點(diǎn)出現(xiàn)問題時(shí)很可能導(dǎo)致出現(xiàn)數(shù)據(jù)丟失問題,比如客戶端向主節(jié)點(diǎn)發(fā)送一條命令,然后主節(jié)點(diǎn)將該命令異步發(fā)送到它的從節(jié)點(diǎn)進(jìn)行數(shù)據(jù)備份,然后立即回復(fù)客戶端命令的執(zhí)行狀態(tài)。如果在這個(gè)過程中,主節(jié)點(diǎn)出現(xiàn)問導(dǎo)致宕機(jī),且從節(jié)點(diǎn)在處理主節(jié)點(diǎn)發(fā)送過來的同步數(shù)據(jù)時(shí),也發(fā)生錯(cuò)誤。這時(shí)正好趕上主節(jié)點(diǎn)宕機(jī)等不可用情況,那么從節(jié)點(diǎn)將轉(zhuǎn)換為新的主節(jié)點(diǎn),在之前主節(jié)點(diǎn)執(zhí)行的命令將丟失。
Redis 集群間通信機(jī)制
在 Redis 集群中,數(shù)據(jù)節(jié)點(diǎn)提供兩個(gè) TCP 端口,在配置防火墻時(shí)需要同時(shí)開啟下面兩類端口:
- 普通端口:即客戶端訪問端口,如默認(rèn)的 6379;
- 集群端口:普通端口號(hào)加 10000,如 6379 的集群端口為 16379,用于集群節(jié)點(diǎn)之間的通訊;
集群的節(jié)點(diǎn)之間通訊采用 Gossip 協(xié)議,節(jié)點(diǎn)根據(jù)固定頻率(每秒10次)定時(shí)任務(wù)進(jìn)行判斷,當(dāng)集群狀態(tài)發(fā)生變化,如增刪節(jié)點(diǎn)、槽狀態(tài)變更時(shí),會(huì)通過節(jié)點(diǎn)間通訊同步集群狀態(tài),使集群收斂。集群間發(fā)送的 Gossip 消息有下面五種消息類型:
- MEET:在節(jié)點(diǎn)握手階段,對(duì)新加入的節(jié)點(diǎn)發(fā)送 meet 消息,請(qǐng)求新節(jié)點(diǎn)加入當(dāng)前集群,新節(jié)點(diǎn)收到消息會(huì)回復(fù) pong 消息;
- PING:節(jié)點(diǎn)之間互相發(fā)送 ping 消息,收到消息的會(huì)回復(fù) pong 消息。ping 消息內(nèi)容包含本節(jié)點(diǎn)和其他節(jié)點(diǎn)的狀態(tài)信息,以此達(dá)到狀態(tài)同步;
- PONG:pong 消息包含自身的狀態(tài)數(shù)據(jù),在接收到 ping 或 meet 消息時(shí)會(huì)回復(fù) pong 消息,也會(huì)主動(dòng)向集群廣播 pong 消息;
- FAIL:當(dāng)一個(gè)主節(jié)點(diǎn)判斷另一個(gè)主節(jié)點(diǎn)進(jìn)入 fail 狀態(tài)時(shí),會(huì)向集群廣播這個(gè)消息,接收到的節(jié)點(diǎn)會(huì)保存該消息并對(duì)該 fail 節(jié)點(diǎn)做狀態(tài)判斷;
- PUBLISH:當(dāng)節(jié)點(diǎn)收到 publish 命令時(shí),會(huì)先執(zhí)行命令,然后向集群廣播 publish 消息,接收到消息的節(jié)點(diǎn)也會(huì)執(zhí)行 publish 命令;
Redis 集群失敗狀態(tài)
在 Redis 集群模式下也不可能百分百保證集群可用性,當(dāng)發(fā)生不可預(yù)知的事件導(dǎo)致 Redis 集群將進(jìn)入失敗狀態(tài),在這種狀態(tài)下 Redis 集群將不能正常提供服務(wù)。其中進(jìn)入失敗狀態(tài)的條件主要為:
① 全部節(jié)點(diǎn)都宕機(jī),集群將進(jìn)入 fail 狀態(tài);
② 半數(shù)以上主節(jié)點(diǎn)不可用,集群將進(jìn)入 fail 狀態(tài);
③ 任意主節(jié)點(diǎn)掛掉,且該主節(jié)點(diǎn)沒有對(duì)應(yīng)的從節(jié)點(diǎn)或者從節(jié)點(diǎn)也全部掛掉,集群將進(jìn)入 fail 狀態(tài);
Redis 集群重新分片機(jī)制
Redis 集群重新分片(新增/移除節(jié)點(diǎn))機(jī)制:
新增節(jié)點(diǎn):別的節(jié)點(diǎn)上的槽分一些出來給新的節(jié)點(diǎn)
刪除節(jié)點(diǎn):刪除節(jié)點(diǎn)的槽分給別的節(jié)點(diǎn)
但這些操作是需要手動(dòng)完成的,可以在不停止服務(wù)器的情況下執(zhí)行。
Redis 集群的不足
復(fù)制結(jié)構(gòu)只支持單層結(jié)構(gòu),不支持樹型結(jié)構(gòu)。
不支持多數(shù)據(jù)庫,只能使用 0 數(shù)據(jù)庫,執(zhí)行 select 0 命令;
鍵是數(shù)據(jù)分區(qū)的最小粒度,不能將一個(gè)很大的鍵值對(duì)映射到不同的節(jié)點(diǎn);
鍵事務(wù)支持有限,當(dāng)多個(gè)鍵分布在不同節(jié)點(diǎn)時(shí)無法使用事務(wù),同一節(jié)點(diǎn)才能支持事務(wù);
鍵的批量操作支持有限,比如 mset, mget 命令,如果多個(gè)鍵映射在不同的槽中,就不能正常使用這些命令了;
Redis 群集配置參數(shù)
我們即將創(chuàng)建一個(gè)示例集群部署。在繼續(xù)之前,讓我們介紹Redis Cluster在redis.conf文件中引入的配置參數(shù)。
cluster-config-file:設(shè)置 Redis 集群配置信息及狀態(tài)的存儲(chǔ)位置,該文件由 Redis 集群生成,我們只能指定其存儲(chǔ)的位置。
cluster-node-timeout:設(shè)置 Redis 群集節(jié)點(diǎn)的通信的超時(shí)時(shí)間;
cluster-migration-barrier:主節(jié)點(diǎn)需要的最小從節(jié)點(diǎn)數(shù),只有達(dá)到這個(gè)數(shù),主節(jié)點(diǎn)失敗時(shí),它從節(jié)點(diǎn)才會(huì)進(jìn)行遷移。
cluster-enabled:是否開啟 Redis 集群模式。
yes:啟用 Redis 群集;
no:不啟用集群模式;
cluster-require-full-coverage:設(shè)置集群可用性。
yes:表示當(dāng)負(fù)責(zé)一個(gè)插槽的主庫下線,且沒有相應(yīng)的從庫進(jìn)行故障恢復(fù)時(shí),集群不可用,下面論證該情況。
no:表示當(dāng)負(fù)責(zé)一個(gè)插槽的主庫下線且沒有相應(yīng)的從庫進(jìn)行故障恢復(fù)時(shí),集群仍然可用,下面論證該情況。
cluster-slave-validity-factor:
0:則無論從節(jié)點(diǎn)與主節(jié)點(diǎn)失聯(lián)多久,從節(jié)點(diǎn)都會(huì)嘗試升級(jí)成主節(jié)點(diǎn)。
正數(shù):則cluster-node-timeout
*
cluster-slave-validity-factor
得到的時(shí)間,是從節(jié)點(diǎn)與主節(jié)點(diǎn)失聯(lián)后,此從節(jié)點(diǎn)數(shù)據(jù)有效的最長時(shí)間,超過這個(gè)時(shí)間,從節(jié)點(diǎn)不會(huì)啟動(dòng)故障遷移。假設(shè)cluster-node-timeout=5
,cluster-slave-validity-factor=10
,則如果從節(jié)點(diǎn)跟主節(jié)點(diǎn)失聯(lián)超過50秒,此從節(jié)點(diǎn)不能成為主節(jié)點(diǎn)。
六、Docker 部署 Redis 集群
1、Redis 部署機(jī)器分配
這里對(duì)待部署的 Redis 集群的節(jié)點(diǎn)進(jìn)行分配,將其部署到不同的機(jī)器上,安排如下:
2、創(chuàng)建數(shù)據(jù)存儲(chǔ)目錄
提前創(chuàng)建好用于存儲(chǔ) Redis 的配置文件和持久化數(shù)據(jù)的目錄:
第一臺(tái)服務(wù)器192.168.2.11
中執(zhí)行創(chuàng)建存儲(chǔ)目錄命令:
$ mkdir -p /var/lib/redis/7000 & mkdir -p /var/lib/redis/7003
第二臺(tái)服務(wù)器192.168.2.12
中執(zhí)行創(chuàng)建存儲(chǔ)目錄命令:
$ mkdir -p /var/lib/redis/7001 & mkdir -p /var/lib/redis/7004
第三臺(tái)服務(wù)器192.168.2.13
中執(zhí)行創(chuàng)建存儲(chǔ)目錄命令:
$ mkdir -p /var/lib/redis/7002 & mkdir -p /var/lib/redis/7005
3、創(chuàng)建 Redis 配置文件
第一臺(tái)服務(wù)器192.168.2.11
配置文件:
##7000端口配置文件 $cat>/var/lib/redis/7000/redis.conf<<EOF port7000 cluster-enabledyes cluster-config-filenodes.conf cluster-node-timeout5000 appendonlyyes daemonizeno protected-modeno pidfile/data/redis.pid EOF ##7003端口配置文件 $cat>/var/lib/redis/7003/redis.conf<<EOF port7003 cluster-enabledyes cluster-config-filenodes.conf cluster-node-timeout5000 appendonlyyes daemonizeno protected-modeno pidfile/data/redis.pid EOF
第二臺(tái)服務(wù)器192.168.2.12
配置文件
## 7001 端口配置:redis.conf $cat>/var/lib/redis/7001/redis.conf<<EOF port7001 cluster-enabledyes cluster-config-filenodes.conf cluster-node-timeout5000 appendonlyyes daemonizeno protected-modeno pidfile/data/redis.pid EOF ## 7004 端口配置:redis-7004.conf $cat>/var/lib/redis/7004/redis.conf<<EOF port7004 cluster-enabledyes cluster-config-filenodes.conf cluster-node-timeout5000 appendonlyyes daemonizeno protected-modeno pidfile/data/redis.pid EOF
第三臺(tái)服務(wù)器192.168.2.13
配置文件
## 7002 端口配置:redis-7002.conf $cat>/var/lib/redis/7002/redis.conf<<EOF port7002 cluster-enabledyes cluster-config-filenodes.conf cluster-node-timeout5000 appendonlyyes daemonizeno protected-modeno pidfile/data/redis.pid EOF ## 7005 端口配置:redis-7005.conf $cat>/var/lib/redis/7005/redis.conf<<EOF port7005 cluster-enabledyes cluster-config-filenodes.conf cluster-node-timeout5000 appendonlyyes daemonizeno protected-modeno pidfile/data/redis.pid EOF
4、提前拉取 Redis 鏡像
三臺(tái)服務(wù)器中提前拉取 Redis 鏡像,避免在執(zhí)行運(yùn)行時(shí)候還得拉取鏡像,導(dǎo)致運(yùn)行慢。
$ docker pull redis:6.0.8
5、運(yùn)行啟動(dòng) Redis 鏡像
三臺(tái)服務(wù)器分別執(zhí)行 Docker 運(yùn)行命令來啟動(dòng) Redis 鏡像。這里需要注意的是,不同服務(wù)器間的 Docker 是不能相互通信的,所有這里我們?cè)O(shè)置啟動(dòng)的容器網(wǎng)絡(luò)模式為 host 模式,這樣容器不會(huì)創(chuàng)建虛擬網(wǎng)卡,而是使用宿主機(jī)的網(wǎng)絡(luò)。
- -d:設(shè)置容器后臺(tái)運(yùn)行;
- -v:指定掛載的宿主機(jī)存儲(chǔ)目錄;
- --name:指定運(yùn)行后的容器名稱;
- --cpus:指定容器使用 CPU 數(shù)量;
- --memory:限制容器使用內(nèi)存數(shù)量;
- --memory-swap:指定交換內(nèi)存大小,這里設(shè)置為 0,即不用交換內(nèi)存;
- --net:指定 Docker 使用的網(wǎng)絡(luò)模式;
- --restart:指定 Docker 重啟時(shí)容器的重啟策略;
- --privileged:設(shè)置容器擁有特權(quán),能夠獲取宿主機(jī) Root 權(quán)限;
第一臺(tái)服務(wù)器192.168.2.11
執(zhí)行如下命令
##運(yùn)行Redis鏡像7000端口 $dockerrun-d-v/var/lib/redis/7000:/data\ --cpus=1--memory=2GB--memory-swap=0\ --privileged=true\ --restart=always\ --nethost\ --nameredis-7000\ redis:6.0.8redis-server/data/redis.conf ##運(yùn)行Redis鏡像7003端口 $dockerrun-d-v/var/lib/redis/7003:/data\ --cpus=1--memory=2GB--memory-swap=0\ --privileged=true\ --restart=always\ --nethost\ --nameredis-7003\ redis:6.0.8redis-server/data/redis.conf
第二臺(tái)服務(wù)器192.168.2.12
執(zhí)行如下命令
##運(yùn)行Redis鏡像7001端口 $dockerrun-d-v/var/lib/redis/7001:/data\ --cpus=1--memory=2GB--memory-swap=0\ --privileged=true\ --restart=always\ --nethost\ --nameredis-7001\ redis:6.0.8redis-server/data/redis.conf ##運(yùn)行Redis鏡像7004端口 $dockerrun-d-v/var/lib/redis/7004:/data\ --cpus=1--memory=2GB--memory-swap=0\ --privileged=true\ --restart=always\ --nethost\ --nameredis-7004\ redis:6.0.8redis-server/data/redis.conf
第三臺(tái)服務(wù)器192.168.2.13
執(zhí)行如下命令:
##運(yùn)行Redis鏡像7002端口 $dockerrun-d-v/var/lib/redis/7002:/data\ --cpus=1--memory=2GB--memory-swap=0\ --privileged=true\ --restart=always\ --nethost\ --nameredis-7002\ redis:6.0.8redis-server/data/redis.conf ##運(yùn)行Redis鏡像7005端口 $dockerrun-d-v/var/lib/redis/7005:/data\ --cpus=1--memory=2GB--memory-swap=0\ --privileged=true\ --restart=always\ --nethost\ --nameredis-7005\ redis:6.0.8redis-server/data/redis.conf
6、創(chuàng)建 Redis 集群
隨意進(jìn)入一臺(tái)服務(wù)器,使用 Redis 鏡像的 redis-cli 工具執(zhí)行創(chuàng)建集群命令使各個(gè) Redis 組成集群,這里本人進(jìn)入第一臺(tái)服務(wù)器192.168.2.11
中,使用端口為7000
的Redis
端鏡像,可以執(zhí)行下面命令:
-p:指定連接 Redis 的端口;
create:創(chuàng)建 Redis 集群;
--cluster:使用 Redis 集群模式命令;
--cluster-replicas:指定副本數(shù)(slave 數(shù)量);
$dockerexec-itredis-7000\ redis-cli-p7000--clustercreate\ 192.168.2.11:7000192.168.2.12:7001192.168.2.13:7002\ 192.168.2.11:7003192.168.2.12:7004192.168.2.13:7005\ --cluster-replicas1
然后會(huì)看到下面信息:
>>>Performinghashslotsallocationon6nodes... Master[0]->Slots0-5460 Master[1]->Slots5461-10922 Master[2]->Slots10923-16383 Addingreplica192.168.2.12:7004to192.168.2.11:7000 Addingreplica192.168.2.13:7005to192.168.2.12:7001 Addingreplica192.168.2.11:7003to192.168.2.13:7002 M:5e50824c55d4df42db4d2987796f0c0b468c273f192.168.2.11:7000 slots:[0-5460](5461slots)master M:36565e0273fd62921aa1f2d85c5f7ac98a5b9466192.168.2.12:7001 slots:[5461-10922](5462slots)master M:0cc1aaf960defae7332e9256dd25ee5e5c99e65f192.168.2.13:7002 slots:[10923-16383](5461slots)master S:42d6e3979395ba93cd1352b6d17044f6b25d9379192.168.2.11:7003 replicates0cc1aaf960defae7332e9256dd25ee5e5c99e65f S:ac5d34b57a8f73dabc60d3a56469055ec64fcde7192.168.2.12:7004 replicates5e50824c55d4df42db4d2987796f0c0b468c273f S:470b7ff823f10a309fb07311097456210506f6d8192.168.2.13:7005 replicates36565e0273fd62921aa1f2d85c5f7ac98a5b9466 CanIsettheaboveconfiguration?(type'yes'toaccept):yes >>>Nodesconfigurationupdated >>>Assignadifferentconfigepochtoeachnode >>>SendingCLUSTERMEETmessagestojointhecluster Waitingfortheclustertojoin . >>>PerformingClusterCheck(usingnode192.168.2.11:7000) M:5e50824c55d4df42db4d2987796f0c0b468c273f192.168.2.11:7000 slots:[0-5460](5461slots)master 1additionalreplica(s) S:470b7ff823f10a309fb07311097456210506f6d8192.168.2.13:7005 slots:(0slots)slave replicates36565e0273fd62921aa1f2d85c5f7ac98a5b9466 S:42d6e3979395ba93cd1352b6d17044f6b25d9379192.168.2.11:7003 slots:(0slots)slave replicates0cc1aaf960defae7332e9256dd25ee5e5c99e65f S:ac5d34b57a8f73dabc60d3a56469055ec64fcde7192.168.2.12:7004 slots:(0slots)slave replicates5e50824c55d4df42db4d2987796f0c0b468c273f M:0cc1aaf960defae7332e9256dd25ee5e5c99e65f192.168.2.13:7002 slots:[10923-16383](5461slots)master 1additionalreplica(s) M:36565e0273fd62921aa1f2d85c5f7ac98a5b9466192.168.2.12:7001 slots:[5461-10922](5462slots)master 1additionalreplica(s) [OK]Allnodesagreeaboutslotsconfiguration. >>>Checkforopenslots... >>>Checkslotscoverage... [OK]All16384slotscovered.
7、查看集群信息
進(jìn)入 Redis 鏡像內(nèi)部并折傭 redis-cli 命令:
-p:指定連接 Redis 的端點(diǎn);
-c:使用集群模式;
$dockerexec-itredis-7000redis-cli-p7000-c
查看集群信息:
>clusterinfo cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:866 cluster_stats_messages_pong_sent:854 cluster_stats_messages_sent:1720 cluster_stats_messages_ping_received:849 cluster_stats_messages_pong_received:866 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:1720
查看集群節(jié)點(diǎn)信息:
>clusternodes 470b7ff823f10a309fb07311097456210506f6d8192.168.2.13:7005@17005slave36565e0273fd62921aa1f2d85c5f7ac98a5b9466016002672170002connected 42d6e3979395ba93cd1352b6d17044f6b25d9379192.168.2.11:7003@17003slave0cc1aaf960defae7332e9256dd25ee5e5c99e65f016002672181713connected ac5d34b57a8f73dabc60d3a56469055ec64fcde7192.168.2.12:7004@17004slave5e50824c55d4df42db4d2987796f0c0b468c273f016002672161611connected 0cc1aaf960defae7332e9256dd25ee5e5c99e65f192.168.2.13:7002@17002master-016002672180703connected10923-16383 36565e0273fd62921aa1f2d85c5f7ac98a5b9466192.168.2.12:7001@17001master-016002672171632connected5461-10922 5e50824c55d4df42db4d2987796f0c0b468c273f192.168.2.11:7000@17000myself,master-016002672170001connected0-5460
參考地址:
http://www.redis.cn/topics/cluster-tutorial.html
http://www.redis.cn/topics/cluster-spec.html
https://jasonkayzk.github.io
https://www.cnblogs.com/kevingrace/p/5685332.html
到此這篇關(guān)于通過Docker部署Redis 6.x集群的方法的文章就介紹到這了,更多相關(guān)Docker部署Redis 6.x集群內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。