Docker中安裝redis cluster集羣

一、新建一個docker橋接網絡

# 創建名稱爲redis-cluster-net的橋接網絡
docker network create -d bridge redis-cluster-net

二、部署redis節點

參照我的這篇文章中的第二節,部署6個redis節點,綁定到宿主機的端口號分別爲6391~6396,需修改的redis.conf配置如下

#bind 127.0.0.1
protected-mode no
cluster-enabled yes

三、使用redis-trib工具創建集羣

這個工具是redis自帶的,但是不能直接在docker中運行,因爲這個工具需要python運行環境,而默認的redis鏡像是沒有python環境的,因此有兩種辦法運行這個工具:一是自己製作一個帶有這個工具命令的docker鏡像,並支持python環境;二是直接使用別人做好的redis-trib鏡像,這裏我就直接用docker hub上現成的鏡像了。

在命令行運行以下命令,創建redis cluster集羣

docker run -it --network redis-cluster-net zvelo/redis-trib create --replicas 1 172.22.0.2:6379 172.22.0.3:6379 172.22.0.4:6379 172.22.0.5:6379 172.22.0.6:6379 172.22.0.7:6379
  • -it表示以交互模式運行容器,因爲創建redis集羣的過程中需要用戶確認一些信息後才能繼續往下執行
  • zvelo/redis-trib是別人創建的redis-trib工具鏡像,會在運行容器前自動下載該鏡像
  • create --replicas 1 172.22.0.2:6379 172.22.0.3:6379 172.22.0.4:6379 172.22.0.5:6379 172.22.0.6:6379 172.22.0.7:6379表示創建redis cluster集羣,默認前面3個爲主節點,後面3個爲從節點,172.22.0.xIP地址是各個redis容器在redis-cluster-net網絡中的IP地址

命令運行過程中的輸出信息如下:

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
172.22.0.2:6379
172.22.0.3:6379
172.22.0.4:6379
Adding replica 172.22.0.5:6379 to 172.22.0.2:6379
Adding replica 172.22.0.6:6379 to 172.22.0.3:6379
Adding replica 172.22.0.7:6379 to 172.22.0.4:6379
M: 508a55e8eb9caa4962c21ac6a5374ef15bfbbb78 172.22.0.2:6379
   slots:0-5460 (5461 slots) master
M: c91fa493fb3a135678887081608e460e23593e34 172.22.0.3:6379
   slots:5461-10922 (5462 slots) master
M: d3d17e760fa04e2cd70897c2719aa9da9d9ddda5 172.22.0.4:6379
   slots:10923-16383 (5461 slots) master
S: de9cee59f2736fdecbc7245420f13d5429a7d8d4 172.22.0.5:6379
   replicates 508a55e8eb9caa4962c21ac6a5374ef15bfbbb78
S: 6815f22140c40b6a8acba5a865b97b12d94c9bdb 172.22.0.6:6379
   replicates c91fa493fb3a135678887081608e460e23593e34
S: 4ece54218638ac07b9ce4b4911bcd19da0c75e7b 172.22.0.7:6379
   replicates d3d17e760fa04e2cd70897c2719aa9da9d9ddda5
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join...
>>> Performing Cluster Check (using node 172.22.0.2:6379)
M: 508a55e8eb9caa4962c21ac6a5374ef15bfbbb78 172.22.0.2:6379
   slots:0-5460 (5461 slots) master
M: c91fa493fb3a135678887081608e460e23593e34 172.22.0.3:6379
   slots:5461-10922 (5462 slots) master
M: d3d17e760fa04e2cd70897c2719aa9da9d9ddda5 172.22.0.4:6379
   slots:10923-16383 (5461 slots) master
M: de9cee59f2736fdecbc7245420f13d5429a7d8d4 172.22.0.5:6379
   slots: (0 slots) master
   replicates 508a55e8eb9caa4962c21ac6a5374ef15bfbbb78
M: 6815f22140c40b6a8acba5a865b97b12d94c9bdb 172.22.0.6:6379
   slots: (0 slots) master
   replicates c91fa493fb3a135678887081608e460e23593e34
M: 4ece54218638ac07b9ce4b4911bcd19da0c75e7b 172.22.0.7:6379
   slots: (0 slots) master
   replicates d3d17e760fa04e2cd70897c2719aa9da9d9ddda5
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

其中,在運行到 Can I set the above configuration? (type ‘yes’ to accept): 時,要輸入 yes 後才能繼續往下執行,執行完畢後,3主3從的redis cluster集羣就創建好了

四、使用Jedis連接redis cluster

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

/**
 * @author chenjc
 * @since 2020-01-08
 */
public class ClusterTest {
    public static void main(String[] args) {
        JedisCluster jedisCluster = new JedisCluster(new HostAndPort("localhost", 6395));
        jedisCluster.set("debo", "666666");
        System.out.println(jedisCluster.get("debo"));
    }
}

連接redis cluster的時候,只需要連接集羣中的任一節點(不分主從),節點間會相互協調,通過 MOVED 和 ASK 等命令,自動定位到key實際應該存儲的節點。

只給Jedis配置一個節點地址是有潛在風險的,當這個節點本身掛掉了,那麼Jedis就失去了和整個redis cluster集羣的聯繫了,所以一般會將全部節點信息給到Jedis,代碼如下

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.util.HashSet;
import java.util.Set;

/**
 * @author chenjc
 * @since 2020-01-08
 */
public class ClusterTest {
    public static void main(String[] args) {
        Set<HostAndPort> nodes = new HashSet<>();
        HostAndPort node1 = new HostAndPort("localhost", 6391);
        HostAndPort node2 = new HostAndPort("localhost", 6392);
        HostAndPort node3 = new HostAndPort("localhost", 6393);
        HostAndPort node4 = new HostAndPort("localhost", 6394);
        HostAndPort node5 = new HostAndPort("localhost", 6395);
        HostAndPort node6 = new HostAndPort("localhost", 6396);
        nodes.add(node1);
        nodes.add(node2);
        nodes.add(node3);
        nodes.add(node4);
        nodes.add(node5);
        nodes.add(node6);
        JedisCluster jedisCluster = new JedisCluster(nodes);
        jedisCluster.set("debo", "666666");
        System.out.println(jedisCluster.get("debo"));
    }
}

也可以使用redis-cli -c -p 6391命令在命令行連接集羣進行相關操作

redis cluster集羣在master節點下線的時候,會自動將slave節點升級爲master,所以redis cluster既支持分片又支持主從自動切換,相較sentinel只支持主從自動切換來說,功能更加強大了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章