共計(jì) 7356 個(gè)字符,預(yù)計(jì)需要花費(fèi) 19 分鐘才能閱讀完成。
本篇內(nèi)容主要講解“redis5.0 集群的安裝過(guò)程”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓丸趣 TV 小編來(lái)帶大家學(xué)習(xí)“redis5.0 集群的安裝過(guò)程”吧!
redis cluster 簡(jiǎn)介
Redis 集群沒(méi)有使用一致性 hash, 而是引入了 哈希槽的概念.
Redis 集群有 16384 個(gè)哈希槽, 每個(gè) key 通過(guò) CRC16 校驗(yàn)后對(duì) 16384 取模來(lái)決定放置哪個(gè)槽. 集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分 hash 槽, 舉個(gè)例子, 比如當(dāng)前集群有 3 個(gè)節(jié)點(diǎn), 那么:
節(jié)點(diǎn) A 包含 0 到 5500 號(hào)哈希槽.
節(jié)點(diǎn) B 包含 5501 到 11000 號(hào)哈希槽.
節(jié)點(diǎn) C 包含 11001 到 16384 號(hào)哈希槽.
這種結(jié)構(gòu)很容易添加或者刪除節(jié)點(diǎn). 比如如果我想新添加個(gè)節(jié)點(diǎn) D, 我需要從節(jié)點(diǎn) A, B, C 中得部分槽到 D 上. 如果我想移除節(jié)點(diǎn) A, 需要將 A 中的槽移到 B 和 C 節(jié)點(diǎn)上, 然后將沒(méi)有任何槽的 A 節(jié)點(diǎn)從集群中移除即可. 由于從一個(gè)節(jié)點(diǎn)將哈希槽移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì)停止服務(wù), 所以無(wú)論添加刪除或者改變某個(gè)節(jié)點(diǎn)的哈希槽的數(shù)量都不會(huì)造成集群不可用的狀態(tài).
圖中描述的是六個(gè) redis 實(shí)例構(gòu)成的集群
6379 端口為客戶端通訊端口
16379 端口為集群總線端口
集群內(nèi)部劃分為 16384 個(gè)數(shù)據(jù)分槽,分布在三個(gè)主 redis 中。
從 redis 中沒(méi)有分槽,不會(huì)參與集群投票,也不會(huì)幫忙加快讀取數(shù)據(jù),僅僅作為主機(jī)的備份。
三個(gè)主節(jié)點(diǎn)中平均分布著 16384 數(shù)據(jù)分槽的三分之一,每個(gè)節(jié)點(diǎn)中不會(huì)存有有重復(fù)數(shù)據(jù),僅僅有自己的從機(jī)幫忙冗余。
注意:redis cluster 至少要有三個(gè)主節(jié)點(diǎn),為了冗余,至少還要有三個(gè)從節(jié)點(diǎn)。
為了使在部分節(jié)點(diǎn)失敗或者大部分節(jié)點(diǎn)無(wú)法通信的情況下集群仍然可用,所以集群使用了主從復(fù)制模型, 每個(gè)節(jié)點(diǎn)都會(huì)有 N - 1 個(gè)復(fù)制品.
在我們例子中具有 A,B,C 三個(gè)節(jié)點(diǎn)的集群, 在沒(méi)有復(fù)制模型的情況下, 如果節(jié)點(diǎn) B 失敗了,那么整個(gè)集群就會(huì)以為缺少 5501-11000 這個(gè)范圍的槽而不可用.
然而如果在集群創(chuàng)建的時(shí)候(或者過(guò)一段時(shí)間)我們?yōu)槊總€(gè)節(jié)點(diǎn)添加一個(gè)從節(jié)點(diǎn) A1,B1,C1, 那么整個(gè)集群便有三個(gè) master 節(jié)點(diǎn)和三個(gè) slave 節(jié)點(diǎn)組成,這樣在節(jié)點(diǎn) B 失敗后,集群便會(huì)選舉 B1 為新的主節(jié)點(diǎn)繼續(xù)服務(wù),整個(gè)集群便不會(huì)因?yàn)椴壅也坏蕉豢捎昧恕?/p>
不過(guò)當(dāng) B 和 B1 都失敗后,集群是不可用的.
Redis 一致性保證
Redis 并不能保證數(shù)據(jù)的強(qiáng)一致性. 這意味這在實(shí)際中集群在特定的條件下可能會(huì)丟失寫操作.
第一個(gè)原因是因?yàn)榧菏怯昧水惒綇?fù)制. 寫操作過(guò)程:
客戶端向主節(jié)點(diǎn) B 寫入一條命令.
主節(jié)點(diǎn) B 向客戶端回復(fù)命令狀態(tài).
主節(jié)點(diǎn)將寫操作復(fù)制給他得從節(jié)點(diǎn) B1, B2 和 B3.
主節(jié)點(diǎn)對(duì)命令的復(fù)制工作發(fā)生在返回命令回復(fù)之后,因?yàn)槿绻看翁幚砻钫?qǐng)求都需要等待復(fù)制操作完成的話,那么主節(jié)點(diǎn)處理命令請(qǐng)求的速度將極大地降低 —— 我們必須在性能和一致性之間做出權(quán)衡。注意:Redis 集群可能會(huì)在將來(lái)提供同步寫的方法。
Redis 集群另外一種可能會(huì)丟失命令的情況是集群出現(xiàn)了網(wǎng)絡(luò)分區(qū),并且一個(gè)客戶端與至少包括一個(gè)主節(jié)點(diǎn)在內(nèi)的少數(shù)實(shí)例被孤立。
舉個(gè)例子 假設(shè)集群包含 A、B、C、A1、B1、C1 六個(gè)節(jié)點(diǎn),其中 A、B、C 為主節(jié)點(diǎn),A1、B1、C1 為 A,B,C 的從節(jié)點(diǎn),還有一個(gè)客戶端 Z1 假設(shè)集群中發(fā)生網(wǎng)絡(luò)分區(qū),那么集群可能會(huì)分為兩方,大部分的一方包含節(jié)點(diǎn) A、C、A1、B1 和 C1,小部分的一方則包含節(jié)點(diǎn) B 和客戶端 Z1 .
Z1 仍然能夠向主節(jié)點(diǎn) B 中寫入, 如果網(wǎng)絡(luò)分區(qū)發(fā)生時(shí)間較短, 那么集群將會(huì)繼續(xù)正常運(yùn)作, 如果分區(qū)的時(shí)間足夠讓大部分的一方將 B1 選舉為新的 master,那么 Z1 寫入 B 中得數(shù)據(jù)便丟失了.
注意,在網(wǎng)絡(luò)分裂出現(xiàn)期間,客戶端 Z1 可以向主節(jié)點(diǎn) B 發(fā)送寫命令的最大時(shí)間是有限制的,這一時(shí)間限制稱為節(jié)點(diǎn)超時(shí)時(shí)間(cluster-node-timeout),是 Redis 集群的一個(gè)重要的配置選項(xiàng):
準(zhǔn)備好兩臺(tái)虛擬機(jī)
node1:172.18.22.100
node2:172.18.22.101
下載最新版 redis 5.0 安裝包
https://redis.io/download
我下載的是 redis-5.0.3.tar.gz
編譯安裝(node1)
[root@node1 ~]# cd /opt/
[root@node1 opt]# tar -xvf redis-5.0.3.tar.gz
[root@node1 opt]# cd redis-5.0.3/
[root@node1 opt]# make MALLOC=lib
[root@node1 opt]# make install
修改配置文件,拷貝到其他機(jī)器上
node1 服務(wù)器上:[root@node1 ~]# cd /opt/
[root@node1 opt]# tar -xvf redis-5.0.3.tar.gz
[root@node1 opt]# cd redis-5.0.3/
[root@node1 redis-5.0.3]# mkdir -p redis_cluster/7000/data
[root@node1 redis-5.0.3]# mkdir -p redis_cluster/7001/data
[root@node1 redis-5.0.3]# mkdir -p redis_cluster/7002/data
在上面的三個(gè)目錄里面創(chuàng)建 redis.conf 文件,需要修改的地方下面已經(jīng)標(biāo)注:
#redis.conf 默認(rèn)配置
daemonize yes
############ 多實(shí)例情況下需修改,例如 redis_6380.pid
pidfile /var/run/redis_7000.pid
############## 多實(shí)例情況下需要修改, 例如 6380
port 7000
tcp-backlog 511
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
################### 多實(shí)例情況下需要修改,例如 6380.log
logfile /var/log/redis_7000.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
################## 多實(shí)例情況下需要修改,例如 dump.6380.rdb
dbfilename dump.7000.rdb
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
####################### 多實(shí)例情況下需要修改, 例如 appendonly_6380.aof
appendfilename appendonly_7000.aof
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
#系統(tǒng)配置
#vim /etc/sysctl.conf
#vm.overcommit_memory = 1
#自定義配置
aof-rewrite-incremental-fsync yes
maxmemory 4096mb
maxmemory-policy allkeys-lru
###################### 多實(shí)例情況下需要修改,例如 /data/6380
dir /opt/redis-5.0.3/redis_cluster/7000/data
#集群配置
cluster-enabled yes
###################### 多實(shí)例情況下需要修改
cluster-config-file /opt/redis-5.0.3/redis_cluster/7000/nodes.conf
cluster-node-timeout 5000
#從 ping 主間隔默認(rèn) 10 秒
#復(fù)制超時(shí)時(shí)間
#repl-timeout 60
#遠(yuǎn)距離主從
#config set client-output-buffer-limit slave 536870912 536870912 0
#config set repl-backlog-size 209715200
[root@node1 redis-5.0.3]# scp -pr /opt/redis-5.0.3/ node2:/opt/
cluster-node-timeout 這個(gè)參數(shù)很重要,設(shè)置太小,會(huì)頻繁發(fā)生主從自動(dòng)切換,設(shè)置時(shí)間太大,會(huì)發(fā)生主宕機(jī)了,不能及時(shí)進(jìn)行主從切換。
一旦某個(gè)主節(jié)點(diǎn)進(jìn)入了 FAIL 狀態(tài),如果這個(gè)主節(jié)點(diǎn)有一個(gè)或者多個(gè)從節(jié)點(diǎn)存在,那么其中一個(gè)從節(jié)點(diǎn)會(huì)被升級(jí)為主節(jié)點(diǎn),而其它從節(jié)點(diǎn)會(huì)開始對(duì)這個(gè)新主節(jié)點(diǎn)進(jìn)行復(fù)制
啟動(dòng)命令,在 node1 和 node2 上執(zhí)行
[root@node1 redis-5.0.3]# /opt/redis-5.0.3/src/redis-server /opt/redis-5.0.3/redis_cluster/7000/redis.conf
[root@node1 redis-5.0.3]# /opt/redis-5.0.3/src/redis-server /opt/redis-5.0.3/redis_cluster/7001/redis.conf
[root@node1 redis-5.0.3]# /opt/redis-5.0.3/src/redis-server /opt/redis-5.0.3/redis_cluster/7002/redis.conf
[root@node1 redis-5.0.3]# /opt/redis-5.0.3/src/redis-cli -h localhost -p 7000 shutdown
[root@node1 redis-5.0.3]# /opt/redis-5.0.3/src/redis-cli -h localhost -p 7000 -c
localhost:7000 ping
PONG
備注:- c 是啟動(dòng)集群模式
創(chuàng)建集群命令
[root@node1 opt]# /opt/redis-5.0.3/src/redis-cli --cluster create 172.18.22.100:7000 172.18.22.100:7001 172.18.22.100:7002 172.18.22.101:7000 172.18.22.101:7001 172.18.22.101:7002 --cluster-replicas 1
中間要輸入一次 yes。
選項(xiàng)–replicas 1 表示我們希望為集群中的每個(gè)主節(jié)點(diǎn)創(chuàng)建一個(gè)從節(jié)點(diǎn)。
查看集群信息
[root@node1 opt]# /opt/redis-5.0.3/src/redis-cli -h localhost -p 7001
localhost:7001 cluster info
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:2
cluster_stats_messages_ping_sent:1302
cluster_stats_messages_pong_sent:946
cluster_stats_messages_meet_sent:4
cluster_stats_messages_sent:2252
cluster_stats_messages_ping_received:945
cluster_stats_messages_pong_received:1306
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:2252
localhost:7001
localhost:7001 CLUSTER NODES
ed9ac7cfe6847f39dfcf56ad4244c4213a0965b1 172.18.22.100:7002@17002 slave f881aa4c6fdce6f7ac058600ca712fd9df110b1a 0 1551346045000 4 connected
fb56d260650dfad25e6b54c1519e9530e1b33b62 172.18.22.100:7001@17001 myself,master - 0 1551346046000 2 connected 10923-16383
09f371cfd0933a343dd6d84159a6f8ad508b1eff 172.18.22.100:7000@17000 master - 0 1551346047131 1 connected 0-5460
a7573d643ede9facb1e9b3b629a1604ed88b6a61 172.18.22.101:7002@17002 slave fb56d260650dfad25e6b54c1519e9530e1b33b62 0 1551346046000 6 connected
f881aa4c6fdce6f7ac058600ca712fd9df110b1a 172.18.22.101:7000@17000 master - 0 1551346046629 4 connected 5461-10922
8d3b210324f24aac0c146363e95d3c87a7eb474c 172.18.22.101:7001@17001 slave 09f371cfd0933a343dd6d84159a6f8ad508b1eff 0 1551346045627 5 connected
集群驗(yàn)證
在第一臺(tái)機(jī)器上連接集群的 7000 端口的節(jié)點(diǎn),在另外一臺(tái)連接 7002 節(jié)點(diǎn),連接方式為 redis-cli -h localhost -c -p 7002 ,
加參數(shù) -C 可連接到集群。
在 7000 節(jié)點(diǎn)執(zhí)行命令 set hello world,執(zhí)行結(jié)果如下:
localhost:7000 set hello world
localhost:7000 get hello
world
然后在另外一臺(tái) 7002 端口,查看 key 為 hello 的內(nèi)容,get hello ,執(zhí)行結(jié)果如下:
localhost:7002 get hello
- Redirected to slot [866] located at 172.18.22.100:7000
world
說(shuō)明集群運(yùn)作正常。
簡(jiǎn)單說(shuō)一下原理
redis cluster 在設(shè)計(jì)的時(shí)候,就考慮到了去中心化,去中間件,也就是說(shuō),集群中的每個(gè)節(jié)點(diǎn)都是平等的關(guān)系,都是對(duì)等的,
每個(gè)節(jié)點(diǎn)都保存各自的數(shù)據(jù)和整個(gè)集群的狀態(tài)。每個(gè)節(jié)點(diǎn)都和其他所有節(jié)點(diǎn)連接,而且這些連接保持活躍,這樣就保證了我
們只需要連接集群中的任意一個(gè)節(jié)點(diǎn),就可以獲取到其他節(jié)點(diǎn)的數(shù)據(jù)。
Redis 集群沒(méi)有并使用傳統(tǒng)的一致性哈希來(lái)分配數(shù)據(jù),而是采用另外一種叫做哈希槽 (hash slot) 的方式來(lái)分配的。
redis cluster 默認(rèn)分配了 16384 個(gè) slot,當(dāng)我們 set 一個(gè) key 時(shí),會(huì)用 CRC16 算法來(lái)取模得到所屬的 slot,然后將這個(gè) key
分到哈希槽區(qū)間的節(jié)點(diǎn)上,具體算法就是:CRC16(key) % 16384。所以我們?cè)跍y(cè)試的時(shí)候看到 set 和 get 的時(shí)候,直接跳轉(zhuǎn)
到了 7000 端口的節(jié)點(diǎn)。
Redis 集群會(huì)把數(shù)據(jù)存在一個(gè) master 節(jié)點(diǎn),然后在這個(gè) master 和其對(duì)應(yīng)的 salve 之間進(jìn)行數(shù)據(jù)同步。當(dāng)讀取數(shù)據(jù)時(shí),
也根據(jù)一致性哈希算法到對(duì)應(yīng)的 master 節(jié)點(diǎn)獲取數(shù)據(jù)。只有當(dāng)一個(gè) master 掛掉之后,才會(huì)啟動(dòng)一個(gè)對(duì)應(yīng)的 salve 節(jié)點(diǎn),
充當(dāng) master。
需要注意的是:必須要 3 個(gè)或以上的主節(jié)點(diǎn),否則在創(chuàng)建集群時(shí)會(huì)失敗,并且當(dāng)存活的主節(jié)點(diǎn)數(shù)小于總節(jié)點(diǎn)數(shù)的一半時(shí),
整個(gè)集群就無(wú)法提供服務(wù)了。
到此,相信大家對(duì)“redis5.0 集群的安裝過(guò)程”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是丸趣 TV 網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!