思維草圖
為什么要使用集群
- 單臺redis內存容量的限制
- 單臺redis并發寫量太大有性能瓶頸
redis集群認識
redis集群是對redis的水平擴容,即啟動N個redis節點,將整個數據分布存儲在這個N個節點中,每個節點存儲總數據的1/N。
如下圖:由3臺master和3臺slave組成的redis集群,每臺master承接客戶端三分之一請求和寫入的數據,當master掛掉后,slave會自動替代master,做到高可用。
配置示例
在一臺機器上,用不同的端口進行服務模擬
創建測試目錄 redis-cluster,并將默認的redis.conf移動到該目錄下
創建master1的配置文件:redis-6379.conf
include /Users/lihui/Documents/dev-tool/redis-cluster/redis.conf
daemonize yes
bind 127.0.0.1
dir /Users/lihui/Documents/dev-tool/redis-cluster/
port 6379
dbfilename dump_6379.rdb
pidfile /Users/lihui/Documents/dev-tool/redis-cluster/var/run/redis_6379.pid
logfile "./6379.log"
# 開啟集群設置
cluster-enabled yes
# 設置節點配置文件
cluster-config-file node-6379.conf
# 設置節點失聯時間,超過該時間(毫秒),集群自動進行主從切換
cluster-node-timeout 15000
創建master2的配置文件:redis-6380.conf
include /Users/lihui/Documents/dev-tool/redis-cluster/redis.conf
daemonize yes
bind 127.0.0.1
dir /Users/lihui/Documents/dev-tool/redis-cluster/
port 6380
dbfilename dump_6380.rdb
pidfile /Users/lihui/Documents/dev-tool/redis-cluster/var/run/redis_6380.pid
logfile "./6380.log"
# 開啟集群設置
cluster-enabled yes
# 設置節點配置文件
cluster-config-file node-6380.conf
# 設置節點失聯時間,超過該時間(毫秒),集群自動進行主從切換
cluster-node-timeout 15000
創建master3的配置文件:redis-6381.conf
include /Users/lihui/Documents/dev-tool/redis-cluster/redis.conf
daemonize yes
bind 127.0.0.1
dir /Users/lihui/Documents/dev-tool/redis-cluster/
port 6381
dbfilename dump_6381.rdb
pidfile /Users/lihui/Documents/dev-tool/redis-cluster/var/run/redis_6381.pid
logfile "./6381.log"
# 開啟集群設置
cluster-enabled yes
# 設置節點配置文件
cluster-config-file node-6381.conf
# 設置節點失聯時間,超過該時間(毫秒),集群自動進行主從切換
cluster-node-timeout 15000
創建slave1的配置文件:redis-6389.conf
include /Users/lihui/Documents/dev-tool/redis-cluster/redis.conf
daemonize yes
bind 127.0.0.1
dir /Users/lihui/Documents/dev-tool/redis-cluster/
port 6389
dbfilename dump_6389.rdb
pidfile /Users/lihui/Documents/dev-tool/redis-cluster/var/run/redis_6389.pid
logfile "./6389.log"
# 開啟集群設置
cluster-enabled yes
# 設置節點配置文件
cluster-config-file node-6389.conf
# 設置節點失聯時間,超過該時間(毫秒),集群自動進行主從切換
cluster-node-timeout 15000
創建slave2的配置文件:redis-6390.conf
include /Users/lihui/Documents/dev-tool/redis-cluster/redis.conf
daemonize yes
bind 127.0.0.1
dir /Users/lihui/Documents/dev-tool/redis-cluster/
port 6390
dbfilename dump_6390.rdb
pidfile /Users/lihui/Documents/dev-tool/redis-cluster/var/run/redis_6390.pid
logfile "./6390.log"
# 開啟集群設置
cluster-enabled yes
# 設置節點配置文件
cluster-config-file node-6390.conf
# 設置節點失聯時間,超過該時間(毫秒),集群自動進行主從切換
cluster-node-timeout 15000
創建slave3的配置文件:redis-6391.conf
include /Users/lihui/Documents/dev-tool/redis-cluster/redis.conf
daemonize yes
bind 127.0.0.1
dir /Users/lihui/Documents/dev-tool/redis-cluster/
port 6391
dbfilename dump_6391.rdb
pidfile /Users/lihui/Documents/dev-tool/redis-cluster/var/run/redis_6391.pid
logfile "./6391.log"
# 開啟集群設置
cluster-enabled yes
# 設置節點配置文件
cluster-config-file node-6391.conf
# 設置節點失聯時間,超過該時間(毫秒),集群自動進行主從切換
cluster-node-timeout 15000
?啟動六個redis服務
redis-server /Users/lihui/Documents/dev-tool/redis-cluster/redis-6379.conf
redis-server /Users/lihui/Documents/dev-tool/redis-cluster/redis-6380.conf
redis-server /Users/lihui/Documents/dev-tool/redis-cluster/redis-6381.conf
redis-server /Users/lihui/Documents/dev-tool/redis-cluster/redis-6389.conf
redis-server /Users/lihui/Documents/dev-tool/redis-cluster/redis-6390.conf
redis-server /Users/lihui/Documents/dev-tool/redis-cluster/redis-6391.conf
啟動之后
確保每一個node文件生成成功
將6個節點合成一個集群
redis-cli --cluster create --cluster-replicas 1
127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381
127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391
注意
- 合體的命令后面會跟上所有節點的ip:port列表,多個之間用空格隔開,注意ip不要寫 127.0.0.1,要寫真實ip (我看別的帖子上是這樣寫的,我自己用127好像可以,但是別學我)
- --cluster-replicas 1:表示采用最簡單的方式配置集群,即每個master配1個slave,6個節點就形成了3主3從
連接集群節點,查看集群信息:cluster nodes
使用 redis-cli -c 命令連接集群中6個節點中任何一個節點都可以,注意和之前的連接參數有點不同 redis-cli 命令后面多了一個 -c 參數,表示采用集群的方式連接,連上以后,然后使用 cluster nodes 可以查看集群節點信息,如下?
集群中的每個節點都會生成一個ID, 這個ID信息會被寫到node-xxxx.conf文件中,節點的ip和端口可能會發生變化,但是節點的ID是不會變的,其他節點可以通過其他節點的ID來認識各個節點。
驗證集群數據的讀寫操作
在 6379 上操作的,但是請求被轉發到了6380這個節點去處理了。這里報錯是因為之前配置沒有寫密碼。
slots(槽)?
- Redis集群內部劃分了16384個slots(插槽),合并的時候,會將每個slots映射到一個master上面。
- 數據庫中的每個key都屬于16384個slots中的其中1個,當通過key讀寫數據的時候,redis需要先根據 key計算出key對應的slots,然后根據slots和master的映射關系找到對應的redis節點,key對應的數據就在這個節點上面。
- 集群中使用公式 CRC16(key)%16384 計算key屬于哪個槽
故障恢復
如果主節點下線,從節點是否能夠提升為主節點?
要等15秒,從節點就會自動變成主節點,如果后續之前的主節點恢復,和之前的主從復制一樣,也是掛在新節點下,成為從節點。
SpringBoot整合redis集群
引入對應的maven
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置redis cluster信息
# 集群節點(host:port),多個之間用逗號隔開
spring.redis.cluster.nodes=ip:port,ip:port,ip:port,ip:port,ip:port,ip:port
# 連接超時時間(毫秒)
spring.redis.timeout=60000