1. 為什么需要集群-高可用性
為什么需要集群-高可用性:
生產環境的實際需求和問題:
容量不夠,redis 如何進行擴容。
并發寫操作,redis 如何分攤。
主從模式,薪火相傳模式,主機宕機,會導致 ip 地址發生變化,應用程序中配置需要修改對應的主機地址,端口等信息。
傳統解決方案 代理主機來解決

上圖解圖:
客戶端請求先到代理服務器
由代理服務器進行請求轉發到對應的業務處理器
為了高可用,代理服務,A服務,B服務,C服務都需要搭建主從結構(至少是一主一從這樣就需求搭建至少 8 臺服務器)。
這種方案的缺點是:成本高,維護困難,如果是一主多從,成本就會更高。
redis3.0 提供解決方案 無中心化集群配置:

各個 Redis 服務仍然采用主從結構。
各個 Redis 服務是連通的,任何一臺服務器,都可以作為請求入口。
各個 Redis 服務器因為是連通的,可以進行請求轉發
這種方式,就無中心化集群配置,可以看到,只需要 6 臺服務器即可搞定。
無中心化集群配置,還會根據 key 值,計算 slot ,把數據分散到不同的主機,從而緩解單個主機的存取壓力
Redis 推薦使用無中心化集群配置。
在實際生成環境,各個 Redis 服務器,應當部署到不同的機器(防止機器宕機,主從復制失效)。
2. 集群概述(及其搭建)
Redis 集群實現了對 Redis 的水平擴容,即啟動 N 個 Redis 節點,將整個數據庫分布存儲在這個 N 個節點中,每個節點存儲總數居的 1 / N
Redis 集群通過分區(partition) 來提供一定程度的可用性(availability) ,即使集群中有一部分節點失效或者無法進行通訊,集群也可以繼續處理命令請求。
Redis 集群搭建:實操演示:

redis.conf配置修改
cluster-enabled yes 打開集群模式 cluster-config-file nodes-6379.conf 設定節點配置文件名 cluster-node-timeout 15000 設定節點失聯時間,超過該時間(毫秒),集群自動進行主 從切換
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


將六個節點合成一個集群


進入到該路徑下后,將六個節點合成一個集群的指令:
如下這個是 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
注意事項和細節:
組合之前,確保所有(你要使用上的端口的) Redis服務器都是啟動的,同時在 root 目錄下(我這里是 root 配置的)nodes-xxxx.conf文件都生成正常。
此時不可以用 127.0.0.1 ,需要使用真實的 IP地址(就是你連接 Linux 的地址,Linux 當中使用ifconfig指令查詢到的地址),在真實生產環境 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


注意事項和細節:
[root@localhost src]# redis-cli -c -p 6379

一個集群至少要有三個主節點。
選項--cluster-replicas 1表示我們希望為集群中的每個主節點創建一個從節點。
分配原則:盡量保證主服務器和從服務器各自運行在不同的 IP 地址(機器),防止機器故障導致主從機制失效,高可用性得不到保障。
3. Redis 集群的使用
什么是 slots:
Redis 集群啟動后, 你會看到如下提示:


一個 Redis 集群包含了16384個插槽(hash slot) ,編號從0-16383,Redis 中的每個鍵都屬于這 16384 個插槽的其中一個。注意:這里雖然只有 16384個插槽,但是并不是只能插入 16384個鍵,多個不同的鍵可以插入到同一個插槽的,并不是一個插槽一個鍵的。
集群使用公式CRC16(key) % 16384來計算鍵 key 屬于哪個槽,其中 CRC16(key) 語句用于計算鍵 key 的 CRC16的校驗和

集群中的每個節點負責處理一部分插槽。舉個例子:如果一個集群可以有主節點,其中
節點 A 負責處理0號 ~ 5460號插槽
節點 B 負責處理5461號 ~ 10922號插槽
節點 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 集群故障恢復
如果主節點下線, 從節點會自動升為主節點(注意 15 秒超時, 再觀察比較準確)
[root@localhost ~]# redis-cli -c -p 6380



這里我們將 6380 主機關閉了。


主節點恢復后,主節點回來變成從機


如果所有某一段插槽的主從節點都宕掉了,Redis 服務是否還能繼續,要根據不同的配置而言。
如果某一段插槽的主從都宕機了,而在 redis.conf 配置文件當中cluster-require-full-coverage為yes,那么,整個集群都會被宕掉,無法使用。
如果某一段插槽的主從都宕機了,而在 redis.conf 配置文件當中cluster-require-full-coverage為no,那么,僅僅只是該段插槽的數據不能使用了,也無法存儲了,其他插槽的數據還可以繼續使用。
redis.conf 文件當中的參數cluster-require-full-coverage

5. Redis 集群的 Jedis 開發(使用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) {
Set set = 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 集群的優缺點
優點:
實現擴容。
分攤壓力。
無中心配置相對簡單。
缺點:
多鍵操作是不被支持的。
多鍵的 Redis 事務是不被支持的。 lua 腳本不被支持
由于集群方案出現較晚,很多公司已經采用了其他的集群方案,而其它方案想要遷移至 redis cluster ,需要整體遷移而不是逐步過渡,復雜度較大。
7. 補充:
將 root 目錄下的,rdb、aof 文件都刪除掉

[root@localhost ~]# rm -f dump*.rdb




8. 最后:
“在這個最后的篇章中,我要表達我對每一位讀者的感激之情。你們的關注和回復是我創作的動力源泉,我從你們身上吸取了無盡的靈感與勇氣。我會將你們的鼓勵留在心底,繼續在其他的領域奮斗。感謝你們,我們總會在某個時刻再次相遇。”
鏈接:https://www.cnblogs.com/TheMagicalRainbowSea/p/18703659
-
服務器
+關注
關注
14文章
10253瀏覽量
91487 -
主機
+關注
關注
0文章
1053瀏覽量
36743 -
應用程序
+關注
關注
38文章
3344瀏覽量
60257 -
Redis
+關注
關注
0文章
392瀏覽量
12186
原文標題:8. 最后:
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
如何構建一個穩定、高性能的Redis集群?
redis集群狀態查看命令
redis查看集群狀態命令
K8S學習教程(二):在 PetaExpress KubeSphere容器平臺部署高可用 Redis 集群
Redis集群操作配置
評論