1. 為什么需要集群-高可用性
為什么需要集群-高可用性:
生產(chǎn)環(huán)境的實(shí)際需求和問(wèn)題:
容量不夠,redis 如何進(jìn)行擴(kuò)容。
并發(fā)寫操作,redis 如何分?jǐn)偂?/p>
主從模式,薪火相傳模式,主機(jī)宕機(jī),會(huì)導(dǎo)致 ip 地址發(fā)生變化,應(yīng)用程序中配置需要修改對(duì)應(yīng)的主機(jī)地址,端口等信息。
傳統(tǒng)解決方案 代理主機(jī)來(lái)解決
上圖解圖:
客戶端請(qǐng)求先到代理服務(wù)器
由代理服務(wù)器進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)到對(duì)應(yīng)的業(yè)務(wù)處理器
為了高可用,代理服務(wù),A服務(wù),B服務(wù),C服務(wù)都需要搭建主從結(jié)構(gòu)(至少是一主一從這樣就需求搭建至少 8 臺(tái)服務(wù)器)。
這種方案的缺點(diǎn)是:成本高,維護(hù)困難,如果是一主多從,成本就會(huì)更高。
redis3.0 提供解決方案 無(wú)中心化集群配置:
各個(gè) Redis 服務(wù)仍然采用主從結(jié)構(gòu)。
各個(gè) Redis 服務(wù)是連通的,任何一臺(tái)服務(wù)器,都可以作為請(qǐng)求入口。
各個(gè) Redis 服務(wù)器因?yàn)槭沁B通的,可以進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)
這種方式,就無(wú)中心化集群配置,可以看到,只需要 6 臺(tái)服務(wù)器即可搞定。
無(wú)中心化集群配置,還會(huì)根據(jù) key 值,計(jì)算 slot ,把數(shù)據(jù)分散到不同的主機(jī),從而緩解單個(gè)主機(jī)的存取壓力
Redis 推薦使用無(wú)中心化集群配置。
在實(shí)際生成環(huán)境,各個(gè) Redis 服務(wù)器,應(yīng)當(dāng)部署到不同的機(jī)器(防止機(jī)器宕機(jī),主從復(fù)制失效)。
2. 集群概述(及其搭建)
Redis 集群實(shí)現(xiàn)了對(duì) Redis 的水平擴(kuò)容,即啟動(dòng) N 個(gè) Redis 節(jié)點(diǎn),將整個(gè)數(shù)據(jù)庫(kù)分布存儲(chǔ)在這個(gè) N 個(gè)節(jié)點(diǎn)中,每個(gè)節(jié)點(diǎn)存儲(chǔ)總數(shù)居的 1 / N
Redis 集群通過(guò)分區(qū)(partition) 來(lái)提供一定程度的可用性(availability) ,即使集群中有一部分節(jié)點(diǎn)失效或者無(wú)法進(jìn)行通訊,集群也可以繼續(xù)處理命令請(qǐng)求。
Redis 集群搭建:實(shí)操演示:
redis.conf配置修改
cluster-enabled yes 打開(kāi)集群模式 cluster-config-file nodes-6379.conf 設(shè)定節(jié)點(diǎn)配置文件名 cluster-node-timeout 15000 設(shè)定節(jié)點(diǎn)失聯(lián)時(shí)間,超過(guò)該時(shí)間(毫秒),集群自動(dòng)進(jìn)行主 從切換
vi /rainbowsea/redis6379.conf, 刪除不必要的內(nèi)容 增加 cluster 配置, 文件最后內(nèi)容,如圖
include /rainbowsea/redis.conf pidfile "/var/run/redis_6379.pid" port 6379 dbfilename "dump6379.rdb" masterauth rainbowsea cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000
[root@localhost rainbowsea]# cp redis6379.conf redis6380.conf [root@localhost rainbowsea]# cp redis6379.conf redis6381.conf [root@localhost rainbowsea]# cp redis6379.conf redis6389.conf [root@localhost rainbowsea]# cp redis6379.conf redis6390.conf [root@localhost rainbowsea]# cp redis6379.conf redis6391.conf [root@localhost rainbowsea]#
使用查找替換修改另外 5 個(gè)文件
換指令 :%s/6379/6380
其它幾個(gè)文件以此操作即可, 操作的時(shí)候,一定要小心, 最后建議再檢查一下
所有的都要加上這個(gè)masterauth rainbowsea加上 Redis 的密碼,沒(méi)有設(shè)置密碼的則不用配置這個(gè)。
所有的都要加上這個(gè)masterauth rainbowsea加上 Redis 的密碼,沒(méi)有設(shè)置密碼的則不用配置這個(gè)。
所有的都要加上這個(gè)masterauth rainbowsea加上 Redis 的密碼,沒(méi)有設(shè)置密碼的則不用配置這個(gè)。
include /rainbowsea/redis.conf pidfile "/var/run/redis_6379.pid" port 6379 dbfilename "dump6379.rdb" masterauth rainbowsea cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000
啟動(dòng) 6 個(gè) Redis 服務(wù)
[root@localhost rainbowsea]# redis-server /rainbowsea/redis6379.conf [root@localhost rainbowsea]# redis-server /rainbowsea/redis6380.conf [root@localhost rainbowsea]# redis-server /rainbowsea/redis6381.conf [root@localhost rainbowsea]# redis-server /rainbowsea/redis6389.conf [root@localhost rainbowsea]# redis-server /rainbowsea/redis6390.conf [root@localhost rainbowsea]# redis-server /rainbowsea/redis6391.conf [root@localhost rainbowsea]# ps -aux | grep redis
將六個(gè)節(jié)點(diǎn)合成一個(gè)集群
進(jìn)入到該路徑下后,將六個(gè)節(jié)點(diǎn)合成一個(gè)集群的指令:
如下這個(gè)是 Redis 沒(méi)有配置密碼的,指令
redis-cli --cluster create --cluster-replicas 1 192.168.76.147:6379 192.168.76.147:6380 192.168.76.147:6381 192.168.76.147:6389 192.168.76.147:6390 192.168.76.147:6391
如下這個(gè)是 Redis 配置了密碼的,指令
redis-cli --cluster create -a rainbowsea --cluster-replicas 1 192.168.76.147:6379 192.168.76.147:6380 192.168.76.147:6381 192.168.76.147:6389 192.168.76.147:6390 192.168.76.147:6391
注意事項(xiàng)和細(xì)節(jié):
組合之前,確保所有(你要使用上的端口的) Redis服務(wù)器都是啟動(dòng)的,同時(shí)在 root 目錄下(我這里是 root 配置的)nodes-xxxx.conf文件都生成正常。
此時(shí)不可以用 127.0.0.1 ,需要使用真實(shí)的 IP地址(就是你連接 Linux 的地址,Linux 當(dāng)中使用ifconfig指令查詢到的地址),在真實(shí)生產(chǎn)環(huán)境 IP都是獨(dú)立的。
replicas 1采用最簡(jiǎn)單的方式配置集群,一臺(tái)主機(jī),一臺(tái)從機(jī),正好三組。
搭建加群如果沒(méi)有成功,把sentinel進(jìn)程關(guān)閉掉,再試一下。
分許主從對(duì)應(yīng)關(guān)系。
分析主從對(duì)應(yīng)關(guān)系:如下
集群方式登錄:
指令: redis-cli -c -p 6379
指令: cluster nodes 命令查看集群信息, 主從的對(duì)應(yīng)關(guān)系, 主要看這里我標(biāo)注的顏色
[root@localhost src]# redis-cli -c -p 6379 127.0.0.1:6379> auth rainbowsea 127.0.0.1:6379> cluster nodes
注意事項(xiàng)和細(xì)節(jié):
[root@localhost src]# redis-cli -c -p 6379
一個(gè)集群至少要有三個(gè)主節(jié)點(diǎn)。
選項(xiàng)--cluster-replicas 1表示我們希望為集群中的每個(gè)主節(jié)點(diǎn)創(chuàng)建一個(gè)從節(jié)點(diǎn)。
分配原則:盡量保證主服務(wù)器和從服務(wù)器各自運(yùn)行在不同的 IP 地址(機(jī)器),防止機(jī)器故障導(dǎo)致主從機(jī)制失效,高可用性得不到保障。
3. Redis 集群的使用
什么是 slots:
Redis 集群?jiǎn)?dòng)后, 你會(huì)看到如下提示:
一個(gè) Redis 集群包含了16384個(gè)插槽(hash slot) ,編號(hào)從0-16383,Redis 中的每個(gè)鍵都屬于這 16384 個(gè)插槽的其中一個(gè)。注意:這里雖然只有 16384個(gè)插槽,但是并不是只能插入 16384個(gè)鍵,多個(gè)不同的鍵可以插入到同一個(gè)插槽的,并不是一個(gè)插槽一個(gè)鍵的。
集群使用公式CRC16(key) % 16384來(lái)計(jì)算鍵 key 屬于哪個(gè)槽,其中 CRC16(key) 語(yǔ)句用于計(jì)算鍵 key 的 CRC16的校驗(yàn)和
集群中的每個(gè)節(jié)點(diǎn)負(fù)責(zé)處理一部分插槽。舉個(gè)例子:如果一個(gè)集群可以有主節(jié)點(diǎn),其中
節(jié)點(diǎn) A 負(fù)責(zé)處理0號(hào) ~ 5460號(hào)插槽
節(jié)點(diǎn) B 負(fù)責(zé)處理5461號(hào) ~ 10922號(hào)插槽
節(jié)點(diǎn) C 負(fù)責(zé)處理10923號(hào) ~ 16383號(hào)插槽
在集群中錄入值:
在 Redis 每次錄入,查詢鍵值,redis 都會(huì)計(jì)算出該 key 應(yīng)該送往的插槽,如果不是該客戶端對(duì)應(yīng)服務(wù)器的插槽,redis 會(huì)告知前往的 Redis 實(shí)例地址和端口。
Redis-cli 客戶端提供了-c參數(shù)實(shí)現(xiàn)自動(dòng)重定向。
如redis-cli -c -p 6379登入后,再錄入,查詢鍵值對(duì)可以自動(dòng)重定向
不在一個(gè) slot 下的鍵值,是不能使用 mget,mset 等多鍵操作。
192.168.76.147:6381> mset k1 "v1" k2 "v2" k3 "v3"
可以通過(guò){}來(lái)定義組的概念,從而使 key 中{}內(nèi)相同內(nèi)容的鍵值對(duì)放到一個(gè)slot中去,就解決了上面 mget 分布到不同 slot 而導(dǎo)致失敗的原因。
192.168.76.147:6381> mest k1{order} "v1" k2{order} "v2" k3{order} "v3"
注意:你如果對(duì)鍵加上了{(lán)}組,那么你想要獲取到該值的時(shí)候,也是要加上對(duì)應(yīng)的{}組的,才能獲取到的。
查詢集群中的值:
指令:CLUSTER KEYSLOT
192.168.76.147:6381> cluster keyslot k1
192.168.76.147:6381> cluster keyslot k2{order}
可以看到歸屬于{}同一組的,Redis都是分配到了同一個(gè) slot 插槽數(shù)值當(dāng)中。
指令:CLUSTER COUNTKEYSINSLOT
192.168.76.147:6381> cluster countkeysinslot 12706 (integer) 1 192.168.76.147:6381> cluster countkeysinslot 16025 (integer) 3
指令:CLUSTER GETKEYSINSLOT
192.168.76.147:6381> cluster getkeysinslot 16025 1 1) "k1{order}" 192.168.76.147:6381> cluster getkeysinslot 16025 2 1) "k1{order}" 2) "k2{order}" 192.168.76.147:6381> cluster getkeysinslot 16025 3
4. Redis 集群故障恢復(fù)
如果主節(jié)點(diǎn)下線, 從節(jié)點(diǎn)會(huì)自動(dòng)升為主節(jié)點(diǎn)(注意 15 秒超時(shí), 再觀察比較準(zhǔn)確)
[root@localhost ~]# redis-cli -c -p 6380
這里我們將 6380 主機(jī)關(guān)閉了。
主節(jié)點(diǎn)恢復(fù)后,主節(jié)點(diǎn)回來(lái)變成從機(jī)
如果所有某一段插槽的主從節(jié)點(diǎn)都宕掉了,Redis 服務(wù)是否還能繼續(xù),要根據(jù)不同的配置而言。
如果某一段插槽的主從都宕機(jī)了,而在 redis.conf 配置文件當(dāng)中cluster-require-full-coverage為yes,那么,整個(gè)集群都會(huì)被宕掉,無(wú)法使用。
如果某一段插槽的主從都宕機(jī)了,而在 redis.conf 配置文件當(dāng)中cluster-require-full-coverage為no,那么,僅僅只是該段插槽的數(shù)據(jù)不能使用了,也無(wú)法存儲(chǔ)了,其他插槽的數(shù)據(jù)還可以繼續(xù)使用。
redis.conf 文件當(dāng)中的參數(shù)cluster-require-full-coverage
5. Redis 集群的 Jedis 開(kāi)發(fā)(使用Java程序連接 Redis 同時(shí)開(kāi)啟集群)
即使連接的不是主機(jī),集群會(huì)自動(dòng)切換主機(jī)進(jìn)行存儲(chǔ),主機(jī)寫,從機(jī)讀。
無(wú)中心化主從集群,無(wú)論從哪臺(tái)主機(jī)寫的數(shù)據(jù),其他主機(jī)上都能讀到數(shù)據(jù)。
注意:需要將 Redis 相關(guān)的端口都打開(kāi) 否則會(huì)報(bào)錯(cuò)
配置防火墻將所有相關(guān) Redis 的端口都打開(kāi)。
[root@localhost src]# firewall-cmd --add-port=6379/tcp --permanent Warning: ALREADY_ENABLED: 6379:tcp success [root@localhost src]# firewall-cmd --add-port=6380/tcp --permanent success [root@localhost src]# firewall-cmd --add-port=6381/tcp --permanent success [root@localhost src]# firewall-cmd --add-port=6389/tcp --permanent success [root@localhost src]# firewall-cmd --add-port=6390/tcp --permanent success [root@localhost src]# firewall-cmd --add-port=6391/tcp --permanent
[root@localhost src]# firewall-cmd --reload
[root@localhost src]# firewall-cmd --list-all
在pom.xml當(dāng)中引入redis.clients依賴。如下:
redis.clients jedis 3.2.0
首先測(cè)試,是否可以連接到 Redis 服務(wù)器。
package com.rainbowsea.jedis; import org.junit.Test; import redis.clients.jedis.Jedis; public class JedisCluster_ { @Test public void con() { // 使用 ip地址 + redis的端口的構(gòu)造器方法 Jedis jedis = new Jedis("192.168.76.147", 6379); // 如果Redis 配置了密碼,則需要進(jìn)行身份校驗(yàn) jedis.auth("rainbowsea"); String ping = jedis.ping(); System.out.println("連接成功 ping 返回的結(jié)果 = " + ping); jedis.close(); // 關(guān)閉當(dāng)前連接,注意并沒(méi)有關(guān)閉 Redis } }
import org.junit.Test; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPoolConfig; import java.util.HashSet; import java.util.Set; public class JedisCluster_ { public static void main(String[] args) { Setset = new HashSet<>(); set.add(new HostAndPort("192.168.76.147", 6379)); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 對(duì)連接池進(jìn)行配置 jedisPoolConfig.setMaxTotal(200); jedisPoolConfig.setMaxIdle(32); jedisPoolConfig.setMaxWaitMillis(60 * 1000); // 單位是毫秒 jedisPoolConfig.setBlockWhenExhausted(true); jedisPoolConfig.setTestOnBorrow(true); JedisCluster jedisCluster = new JedisCluster(set,5000,5000,5,"rainbowsea",jedisPoolConfig ); jedisCluster.set("address", "bj"); String address = jedisCluster.get("address"); System.out.println("address=>" + address); jedisCluster.close(); } }
6. Redis 集群的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
實(shí)現(xiàn)擴(kuò)容。
分?jǐn)倝毫Α?/p>
無(wú)中心配置相對(duì)簡(jiǎn)單。
缺點(diǎn):
多鍵操作是不被支持的。
多鍵的 Redis 事務(wù)是不被支持的。 lua 腳本不被支持
由于集群方案出現(xiàn)較晚,很多公司已經(jīng)采用了其他的集群方案,而其它方案想要遷移至 redis cluster ,需要整體遷移而不是逐步過(guò)渡,復(fù)雜度較大。
7. 補(bǔ)充:
將 root 目錄下的,rdb、aof 文件都刪除掉
[root@localhost ~]# rm -f dump*.rdb
8. 最后:
“在這個(gè)最后的篇章中,我要表達(dá)我對(duì)每一位讀者的感激之情。你們的關(guān)注和回復(fù)是我創(chuàng)作的動(dòng)力源泉,我從你們身上吸取了無(wú)盡的靈感與勇氣。我會(huì)將你們的鼓勵(lì)留在心底,繼續(xù)在其他的領(lǐng)域奮斗。感謝你們,我們總會(huì)在某個(gè)時(shí)刻再次相遇。”
鏈接:https://www.cnblogs.com/TheMagicalRainbowSea/p/18703659
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
9556瀏覽量
86844 -
主機(jī)
+關(guān)注
關(guān)注
0文章
1029瀏覽量
35698 -
應(yīng)用程序
+關(guān)注
關(guān)注
38文章
3312瀏覽量
58451 -
Redis
+關(guān)注
關(guān)注
0文章
381瀏覽量
11199
原文標(biāo)題:8. 最后:
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
如何構(gòu)建一個(gè)穩(wěn)定、高性能的Redis集群?

redis集群狀態(tài)查看命令
redis集群中的hash一致性算法的理解
redis集群性能測(cè)試工具有哪些
redis查看集群狀態(tài)命令
K8S學(xué)習(xí)教程(二):在 PetaExpress KubeSphere容器平臺(tái)部署高可用 Redis 集群

評(píng)論