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

redis集群狀態(tài)查看命令
redis集群性能測試工具有哪些
redis查看集群狀態(tài)命令
K8S學習教程(二):在 PetaExpress KubeSphere容器平臺部署高可用 Redis 集群

評論