Redis集群方案
1 redis-cluster架構圖

架構細節:
(1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬.
(2)節點的fail是通過集群中超過半數的節點檢測有效時整個集群才生效.
(3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可
(4)redis-cluster把所有的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->value
Redis 集群中內置了 16384 個哈希槽,當需要在 Redis 集群中放置一個 key-value 時,redis 先對 key 使用 crc16 演算法算出一個結果,然后把結果對 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽, redis 會根據節點數量大致均等的將哈希槽映射到不同的節點
示例如下:

2 redis-cluster投票:容錯

心跳機制
(1)集群中所有master參與投票,如果半數以上master節點與其中一個master節點通信超過(cluster-node-timeout), 認為該master節點掛掉.
(2):什么時候整個集群不可用(cluster_state:fail)?
? 如果集群任意master掛掉,且當前master沒有slave,則集群進入fail狀態,也可以理解成集群的[0-16383]slot映 射不完全時進入fail狀態,
? 如果集群超過半數以上master掛掉,無論是否有slave,集群進入fail狀態,
3 集群搭建步驟
第一步:安裝redis
第二步:創建集群目錄
[root@localhost redis]# mkdir redis-cluster
第三步:在集群目錄下創建節點目錄

搭建集群最少也得需要3臺主機,如果每臺主機再配置一臺從機的話,則最少需要6臺機器, 設計埠如下:創建6 個redis實體,需要埠號7001~7006
[root@localhost myapps]# cp redis/ redis-cluster/7001 -r
[root@localhost myapps]# cd redis-cluster/7001
[root@localhost 7001]# ll
drwxr-xr-x. 2 root root 4096 7月 1 10:22 bin
-rw-r--r--. 1 root root 3446 7月 1 10:22 dump.rdb
-rw-r--r--. 1 root root 41404 7月 1 10:22 redis.conf
第四步:如果存在持久化檔案,則洗掉
[root@localhost 7001]# rm -rf appendonly.aof dump.rdb
第五步:修改redis.conf組態檔,打開Cluster-enable yes
說明:cluster-enable 是否支持集群

第六步:修改埠

第七步:復制出7002-7006機器
[root@localhost redis-cluster]# cp 7001/ 7002 -r
[root@localhost redis-cluster]# cp 7001/ 7003 -r
[root@localhost redis-cluster]# cp 7001/ 7004 -r
[root@localhost redis-cluster]# cp 7001/ 7005 -r
[root@localhost redis-cluster]# cp 7001/ 7006 -r
[root@localhost redis-cluster]# ll
total 28
drwxr-xr-x. 3 root root 4096 Jun 2 00:02 7001
drwxr-xr-x. 3 root root 4096 Jun 2 00:02 7002
drwxr-xr-x. 3 root root 4096 Jun 2 00:02 7003
drwxr-xr-x. 3 root root 4096 Jun 2 00:03 7004
drwxr-xr-x. 3 root root 4096 Jun 2 00:03 7005
drwxr-xr-x. 3 root root 4096 Jun 2 00:03 7006
-rwxr-xr-x. 1 root root 3600 Jun 1 23:52 redis-trib.rb
第八步:修改7002-7006機器的埠
第九步:啟動7001-7006這六臺機器,寫一個啟動腳本:自定義shel腳本
[root@localhost redis-cluster]# vi startall.sh
內容:
cd 7001
./bin/redis-server ./redis.conf
cd ..
cd 7002
./bin/redis-server ./redis.conf
cd ..
cd 7003
./bin/redis-server ./redis.conf
cd ..
cd 7004
./bin/redis-server ./redis.conf
cd ..
cd 7005
./bin/redis-server ./redis.conf
cd ..
cd 7006
./bin/redis-server ./redis.conf
cd ..
第十步:修改start-all.sh檔案的權限
[root@localhost redis-cluster]# chmod u+x startall.sh
第十一步:啟動所有的實體
[root@localhost redis-cluster]# ./startall.sh
第十二步:創建集群(關閉防火墻)
注意:在任意一臺上運行 不要在每臺機器上都運行,一臺就夠了 redis 5.0.5中使用redis-cli --cluster替代redistrib.rb,命令如下
redis-cli --cluster create ip:port ip:port --cluster-replicas 1
[root@localhost redis_cluster]# cd /home/admin/myapps/redis-cluster/7001/bin
[root@localhost bin]# ./redis-cli --cluster create 192.168.197.132:7001 192.168.197.132:7002
192.168.197.132:7003 192.168.197.132:7004 192.168.197.132:7005 192.168.197.132:7006 --clusterreplicas 1
\>>> Creating cluster
Connecting to node 127.0.0.1:7001: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7003: OK
Connecting to node 127.0.0.1:7004: OK
Connecting to node 127.0.0.1:7005: OK
Connecting to node 127.0.0.1:7006: OK
\>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
Adding replica 127.0.0.1:7006 to 127.0.0.1:7003
[OK] All 16384 slots covered.
4 連接集群
命令:
[root@localhost 7001]# ./bin/redis-cli -h 127.0.0.1 -p 7001 -c
-c:指定是集群連接
[root@localhost 7001]# ./bin/redis-cli -h 127.0.0.1 -p 7001 -c
127.0.0.1:7001> set username java123
-> Redirected to slot [14315] located at 127.0.0.1:7003
OK
關閉防火墻:service iptables stop
查看防火墻狀態:service iptables status
5 查看集群資訊
127.0.0.1:7003> 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:3
cluster_stats_messages_sent:1186
cluster_stats_messages_received:1186
6 查看集群中節點資訊
127.0.0.1:7003> cluster nodes
713218b88321e5067fd8ad25c3bf7db88c878ccf 127.0.0.1:7003 myself,master - 0 0 3 connected 10923-
16383
e7fb45e74f828b53ccd8b335f3ed587aa115b903 127.0.0.1:7001 master - 0 1498877677276 1 connected 0-
5460
b1183545245b3a710a95d669d7bbcbb5e09896a0 127.0.0.1:7006 slave
713218b88321e5067fd8ad25c3bf7db88c878ccf 0 1498877679294 3 connected
8879c2ed9c141de70cb7d5fcb7d690ed8a200792 127.0.0.1:7005 slave
4a312b6fc90bfee187d43588ead99d83b407c892 0 1498877678285 5 connected
4a312b6fc90bfee187d43588ead99d83b407c892 127.0.0.1:7002 master - 0 1498877674248 2 connected
5461-10922
4f8c7455574e2f0aab1e2bb341eae319ac065039 127.0.0.1:7004 slave
e7fb45e74f828b53ccd8b335f3ed587aa115b903 0 1498877680308 4 connected
7 Jedis連接集群
7.1 關閉防火墻
注意:如果redis重啟,需要將redis中生成的dump.rdb和nodes.conf檔案洗掉,然后再重啟,
7.2 代碼實作
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
注意jedis的版本,其他版本有可能報錯:java.lang.NumberFormatException: For input string: “7002@17002”
public static void main(String[] args) throws IOException {
// 創建一連接,JedisCluster物件,在系統中是單例存在
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
nodes.add(new HostAndPort("192.168.197.132", 7001));
nodes.add(new HostAndPort("192.168.197.132", 7002));
nodes.add(new HostAndPort("192.168.197.132", 7003));
nodes.add(new HostAndPort("192.168.197.132", 7004));
nodes.add(new HostAndPort("192.168.197.132", 7005));
nodes.add(new HostAndPort("192.168.197.132", 7006));
JedisCluster cluster = new JedisCluster(nodes);
// 執行JedisCluster物件中的方法,方法和redis指令一一對應,
cluster.set("test1", "test111");
String result = cluster.get("test1");
System.out.println(result);
//存盤List資料到串列中
cluster.lpush("site-list", "java");
cluster.lpush("site-list", "c");
cluster.lpush("site-list", "mysql");
// 獲取存盤的資料并輸出
List<String> list = cluster.lrange("site-list", 0 ,2);
for(int i=0; i<list.size(); i++) {
System.out.println("串列項為: "+list.get(i));
}
// 程式結束時需要關閉JedisCluster物件
cluster.close();
System.out.println("集群測驗成功!");
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/252661.html
標籤:其他
上一篇:基于seata官網示例改造的最新版本 Spring Cloud Alibaba + OpenFeign + Druid + Seata 分布式事務演練
