Redis分片集群的實(shí)現(xiàn)
1. Redis Cluster的核心概念
哈希槽(Hash Slots)
Redis Cluster使用哈希槽來(lái)實(shí)現(xiàn)數(shù)據(jù)分片。整個(gè)數(shù)據(jù)空間被劃分為16384個(gè)哈希槽(slot),這些槽均勻分布到不同的主節(jié)點(diǎn)上。
- 哈希計(jì)算:對(duì)于每一個(gè)鍵,Redis使用CRC16算法計(jì)算其哈希值,并對(duì)16384取模,確定該鍵屬于哪個(gè)哈希槽。
- 槽分配:每個(gè)主節(jié)點(diǎn)負(fù)責(zé)一部分哈希槽。例如,如果有三個(gè)主節(jié)點(diǎn),它們可以分別負(fù)責(zé)5461個(gè)哈希槽。
主從復(fù)制與故障轉(zhuǎn)移
為了保證高可用性,每個(gè)主節(jié)點(diǎn)都有一個(gè)或多個(gè)從節(jié)點(diǎn)。當(dāng)主節(jié)點(diǎn)發(fā)生故障時(shí),集群會(huì)自動(dòng)進(jìn)行故障轉(zhuǎn)移,提升其中一個(gè)從節(jié)點(diǎn)為新的主節(jié)點(diǎn)。
- 主從同步:從節(jié)點(diǎn)會(huì)持續(xù)地從主節(jié)點(diǎn)同步數(shù)據(jù),以保持?jǐn)?shù)據(jù)的一致性。同步過(guò)程包括全量同步和增量同步。
- 故障檢測(cè)與恢復(fù):集群中的節(jié)點(diǎn)會(huì)定期交換信息,監(jiān)測(cè)其他節(jié)點(diǎn)的狀態(tài)。如果某個(gè)主節(jié)點(diǎn)失效,集群會(huì)選擇一個(gè)從節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn),并重新分配哈希槽。
2. 詳細(xì)的配置步驟
準(zhǔn)備節(jié)點(diǎn)
假設(shè)我們有6個(gè)Redis實(shí)例(3個(gè)主節(jié)點(diǎn)和3個(gè)從節(jié)點(diǎn)),分別運(yùn)行在不同的端口上。
節(jié)點(diǎn)配置示例 (redis-node.conf)
每個(gè)節(jié)點(diǎn)的配置文件略有不同,主要是端口號(hào)和角色的不同。以下是每個(gè)節(jié)點(diǎn)的配置文件示例:
主節(jié)點(diǎn)1: redis-node1.conf (Port: 7000)
# 端口號(hào) port 7000 # 啟用集群模式 cluster-enabled yes # 集群配置文件路徑,用于存儲(chǔ)集群狀態(tài)信息 cluster-config-file nodes-7000.conf # 節(jié)點(diǎn)超時(shí)時(shí)間(毫秒),超過(guò)此時(shí)間未響應(yīng)視為故障 cluster-node-timeout 5000 # 開(kāi)啟AOF持久化 appendonly yes # 可選配置項(xiàng) # 設(shè)置密碼保護(hù) # requirepass yourpassword # 設(shè)置最大內(nèi)存使用量 # maxmemory 2gb # 設(shè)置持久化策略 # appendfsync everysec
從節(jié)點(diǎn)1: redis-node2.conf (Port: 7001)
# 端口號(hào) port 7001 # 啟用集群模式 cluster-enabled yes # 集群配置文件路徑,用于存儲(chǔ)集群狀態(tài)信息 cluster-config-file nodes-7001.conf # 節(jié)點(diǎn)超時(shí)時(shí)間(毫秒),超過(guò)此時(shí)間未響應(yīng)視為故障 cluster-node-timeout 5000 # 開(kāi)啟AOF持久化 appendonly yes # 設(shè)置從節(jié)點(diǎn)的主節(jié)點(diǎn) slaveof 127.0.0.1 7000 # 可選配置項(xiàng) # 設(shè)置密碼保護(hù) # requirepass yourpassword # 設(shè)置最大內(nèi)存使用量 # maxmemory 2gb # 設(shè)置持久化策略 # appendfsync everysec
主節(jié)點(diǎn)2: redis-node3.conf (Port: 7002)
port 7002 cluster-enabled yes cluster-config-file nodes-7002.conf cluster-node-timeout 5000 appendonly yes
從節(jié)點(diǎn)2: redis-node4.conf (Port: 7003)
port 7003 cluster-enabled yes cluster-config-file nodes-7003.conf cluster-node-timeout 5000 appendonly yes slaveof 127.0.0.1 7002
主節(jié)點(diǎn)3: redis-node5.conf (Port: 7004)
port 7004 cluster-enabled yes cluster-config-file nodes-7004.conf cluster-node-timeout 5000 appendonly yes
從節(jié)點(diǎn)3: redis-node6.conf (Port: 7005)
port 7005 cluster-enabled yes cluster-config-file nodes-7005.conf cluster-node-timeout 5000 appendonly yes slaveof 127.0.0.1 7004
啟動(dòng)節(jié)點(diǎn)
依次啟動(dòng)所有節(jié)點(diǎn):
redis-server /path/to/redis-node1.conf redis-server /path/to/redis-node2.conf redis-server /path/to/redis-node3.conf redis-server /path/to/redis-node4.conf redis-server /path/to/redis-node5.conf redis-server /path/to/redis-node6.conf
創(chuàng)建集群
使用redis-cli
工具創(chuàng)建集群:
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
這里的--cluster-replicas 1
表示每個(gè)主節(jié)點(diǎn)有一個(gè)從節(jié)點(diǎn)。
3. 實(shí)際操作示例
寫(xiě)入數(shù)據(jù)
你可以像平常一樣寫(xiě)入數(shù)據(jù),Redis Cluster會(huì)自動(dòng)將數(shù)據(jù)分配到合適的節(jié)點(diǎn)上。
redis-cli -c -p 7000 127.0.0.1:7000> SET key1 value1 -> Redirected to slot [12182] located at 127.0.0.1:7002 OK
注意這里-c
參數(shù)表示啟用集群模式,這樣客戶端會(huì)自動(dòng)處理重定向命令。
讀取數(shù)據(jù)
讀取數(shù)據(jù)時(shí),同樣可以通過(guò)任意節(jié)點(diǎn)訪問(wèn):
redis-cli -c -p 7000 127.0.0.1:7000> GET key1 -> Redirected to slot [12182] located at 127.0.0.1:7002 "value1"
故障模擬與恢復(fù)
你可以手動(dòng)關(guān)閉一個(gè)主節(jié)點(diǎn)來(lái)模擬故障,并觀察集群如何進(jìn)行自動(dòng)故障轉(zhuǎn)移。
關(guān)閉主節(jié)點(diǎn)
redis-cli -p 7002 shutdown
檢查集群狀態(tài)
redis-cli -p 7000 cluster nodes
你應(yīng)該看到原來(lái)的從節(jié)點(diǎn)已經(jīng)被提升為主節(jié)點(diǎn),并接管了原主節(jié)點(diǎn)的哈希槽。
4. Redis Cluster的內(nèi)部機(jī)制
數(shù)據(jù)分片與重定向
- 數(shù)據(jù)分片:每個(gè)鍵通過(guò)哈希槽映射到特定的主節(jié)點(diǎn)??蛻舳税l(fā)送的請(qǐng)求會(huì)被路由到相應(yīng)的節(jié)點(diǎn)。
- 重定向:如果客戶端請(qǐng)求了一個(gè)不屬于當(dāng)前節(jié)點(diǎn)的哈希槽,集群會(huì)返回一個(gè)
MOVED
響應(yīng),指示客戶端應(yīng)該連接到正確的節(jié)點(diǎn),客戶端收到這個(gè)響應(yīng)后,會(huì)自動(dòng)重定向到指定的節(jié)點(diǎn)。
# 連接到集群中的任意節(jié)點(diǎn) redis-cli -c -p 7000 # 嘗試設(shè)置一個(gè)鍵 127.0.0.1:7000> SET key1 value1 -> Redirected to slot [12182] located at 127.0.0.1:7002 OK # 從同一個(gè)客戶端再次嘗試獲取相同的鍵 127.0.0.1:7000> GET key1 -> Redirected to slot [12182] located at 127.0.0.1:7002 "value1"
主從復(fù)制與故障轉(zhuǎn)移
- 主從同步:從節(jié)點(diǎn)會(huì)持續(xù)地從主節(jié)點(diǎn)同步數(shù)據(jù),以保持?jǐn)?shù)據(jù)的一致性。同步過(guò)程包括全量同步和增量同步。
- 全量同步:首次同步時(shí),從節(jié)點(diǎn)會(huì)從主節(jié)點(diǎn)獲取完整的數(shù)據(jù)集。
- 過(guò)程:從節(jié)點(diǎn)向主節(jié)點(diǎn)發(fā)起全量同步請(qǐng)求,主節(jié)點(diǎn)生成RDB文件并傳輸給從節(jié)點(diǎn)。從節(jié)點(diǎn)加載RDB文件并開(kāi)始接收后續(xù)的增量更新。
- 增量同步:后續(xù)同步時(shí),從節(jié)點(diǎn)會(huì)接收主節(jié)點(diǎn)的增量更新(如寫(xiě)操作日志)。
- 過(guò)程:主節(jié)點(diǎn)記錄寫(xiě)操作日志(稱為復(fù)制積壓緩沖區(qū)),從節(jié)點(diǎn)根據(jù)偏移量請(qǐng)求缺失的部分日志。
- 全量同步:首次同步時(shí),從節(jié)點(diǎn)會(huì)從主節(jié)點(diǎn)獲取完整的數(shù)據(jù)集。
- 故障檢測(cè):集群中的節(jié)點(diǎn)會(huì)定期交換信息,監(jiān)測(cè)其他節(jié)點(diǎn)的狀態(tài)。如果某個(gè)主節(jié)點(diǎn)連續(xù)多次未能響應(yīng)心跳消息,它會(huì)被標(biāo)記為疑似下線(PFAIL)。
- 心跳檢查:每個(gè)節(jié)點(diǎn)會(huì)定期向其他節(jié)點(diǎn)發(fā)送心跳消息,默認(rèn)間隔是1秒。
- 標(biāo)記PFAIL:如果一個(gè)節(jié)點(diǎn)在一定時(shí)間內(nèi)沒(méi)有回應(yīng)心跳消息,它會(huì)被標(biāo)記為疑似下線(PFAIL)。
- 標(biāo)記FAIL:如果大多數(shù)節(jié)點(diǎn)都標(biāo)記某個(gè)節(jié)點(diǎn)為PFAIL,則該節(jié)點(diǎn)會(huì)被標(biāo)記為FAIL。
- 故障轉(zhuǎn)移:一旦主節(jié)點(diǎn)被確認(rèn)下線,集群會(huì)選擇一個(gè)從節(jié)點(diǎn)提升為主節(jié)點(diǎn),并重新分配哈希槽。具體步驟如下:選舉:集群中的節(jié)點(diǎn)會(huì)選舉一個(gè)新的主節(jié)點(diǎn)。選舉過(guò)程基于Raft一致性算法,確保只有一個(gè)從節(jié)點(diǎn)被選中。
- 投票過(guò)程:每個(gè)從節(jié)點(diǎn)會(huì)根據(jù)一定的規(guī)則投票給一個(gè)候選者。最終得票最多的從節(jié)點(diǎn)會(huì)被選為新的主節(jié)點(diǎn)。
- 部分同步:如果從節(jié)點(diǎn)已經(jīng)有部分?jǐn)?shù)據(jù),可以只同步缺失的部分?jǐn)?shù)據(jù)。
- 全量同步:如果從節(jié)點(diǎn)的數(shù)據(jù)完全丟失,需要進(jìn)行全量同步。
重新分配哈希槽:新的主節(jié)點(diǎn)接管原主節(jié)點(diǎn)的哈希槽,集群恢復(fù)正常服務(wù)。
5. 總結(jié)
Redis Cluster通過(guò)哈希槽實(shí)現(xiàn)了數(shù)據(jù)的分布式存儲(chǔ),并提供了高可用性和自動(dòng)故障轉(zhuǎn)移功能。這使得它非常適合于需要處理大量數(shù)據(jù)和高并發(fā)請(qǐng)求的應(yīng)用場(chǎng)景。同時(shí),現(xiàn)代的Redis客戶端庫(kù)也能夠很好地支持集群模式下的自動(dòng)重定向和負(fù)載均衡。
到此這篇關(guān)于Redis分片集群的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Redis分片集群內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis調(diào)用Lua腳本及使用場(chǎng)景快速掌握
Redis?是一種非常流行的內(nèi)存數(shù)據(jù)庫(kù),常用于數(shù)據(jù)緩存與高頻數(shù)據(jù)存儲(chǔ)。大多數(shù)開(kāi)發(fā)人員可能聽(tīng)說(shuō)過(guò)redis可以運(yùn)行?Lua?腳本,但是可能不知道redis在什么情況下需要使用到Lua腳本2022-03-03Redis使用命令行與多數(shù)據(jù)庫(kù)配置
本文詳細(xì)講解了Redis使用命令行與多數(shù)據(jù)庫(kù)配置的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03聊聊使用RedisTemplat實(shí)現(xiàn)簡(jiǎn)單的分布式鎖的問(wèn)題
這篇文章主要介紹了使用RedisTemplat實(shí)現(xiàn)簡(jiǎn)單的分布式鎖問(wèn)題,文中給大家介紹在SpringBootTest中編寫(xiě)測(cè)試模塊的詳細(xì)代碼,需要的朋友可以參考下2021-11-11基于Redis實(shí)現(xiàn)搶紅包和發(fā)紅包功能
搶紅包是我們生活常用的社交功能, 這個(gè)功能最主要的特點(diǎn)就是用戶的并發(fā)請(qǐng)求高, 在系統(tǒng)設(shè)計(jì)上, 可以使用非常多的辦法來(lái)扛住用戶的高并發(fā)請(qǐng)求, 在本文中簡(jiǎn)要介紹使用Redis緩存中間件來(lái)實(shí)現(xiàn)搶紅包算法,需要的朋友可以參考下2024-04-04關(guān)于Redis解決Session共享問(wèn)題
這篇文章主要介紹了Redis解決Session共享問(wèn)題,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Redis教程(六):Sorted-Sets數(shù)據(jù)類型
這篇文章主要介紹了Redis教程(六):Sorted-Sets數(shù)據(jù)類型,本文講解了Sorted-Sets數(shù)據(jù)類型概述、相關(guān)命令列表、命令使用示例、應(yīng)用范圍等內(nèi)容,需要的朋友可以參考下2015-04-04基于redis實(shí)現(xiàn)世界杯排行榜功能項(xiàng)目實(shí)戰(zhàn)
前段時(shí)間,做了一個(gè)世界杯競(jìng)猜積分排行榜。對(duì)世界杯64場(chǎng)球賽勝負(fù)平進(jìn)行猜測(cè),猜對(duì)+1分,錯(cuò)誤+0分,一人一場(chǎng)只能猜一次。下面通過(guò)本文給大家分享基于redis實(shí)現(xiàn)世界杯排行榜功能項(xiàng)目實(shí)戰(zhàn),感興趣的朋友一起看看吧2018-10-10