Docker中安裝redis主從節點和sentinel集羣

一、準備工作

需要先創建一個docker網絡,類型爲橋接網絡,後面會將redis主從節點和sentinel集羣都加入到這網絡中,目的是保證全部節點的相互連通。

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

注:其實可以不用特意創建一個網絡,默認所有節點會自動加入到名稱爲bridge的橋接網絡中,這個網絡是默認已存在的

二、部署redis節點

  1. 在自己電腦上建一個文件夾,然後放一個redis-6380.conf配置文件,這個配置文件直接拷貝的默認的redis.conf配置文件(實不相瞞,我就是用的redis官網的redis4.0.14配置文件),只需修改如下兩個配置:
#bind 127.0.0.1
protected-mode no
  1. 在命令行運行以下命令,用來在docker容器中啓動一個redis節點
docker run -d -p 6380:6379 --name redis-node-6380 --network redis-net --mount type=bind,source=/home/debo/dockerData/redis/redis-6380.conf,target=/etc/redis.conf redis:4.0.14 redis-server /etc/redis.conf
  • -d表示在後臺運行
  • -p 6380:6379表示將容器中的6379端口綁定到宿主機的6380端口,這樣就可以在容器外部使用localhost:6380訪問這個redis
  • --name redis-node-6380表示容器名稱是redis-node-6380
  • --network redis-net表示加入redis-net網絡
  • --mount type=bind,source=/home/debo/dockerData/redis/redis-6380.conf,target=/etc/redis.conf表示將宿主機的redis-6380.conf文件掛載到容器中/etc/redis.conf下
  • redis:4.0.14 redis-server /etc/redis.conf表示使用鏡像redis:4.0.14啓動容器,如果沒有這鏡像,會自動從鏡像倉庫下載的,同時啓動成功後執行redis-server命令並使用容器中的/etc/redis.conf作爲配置文件
  1. 將redis-6380.conf文件複製兩份,分別重命名爲redis-6381.conf和redis-6382.conf,然後依次執行如下命令,完成另外兩個redis節點的部署
docker run -d -p 6381:6379 --name redis-node-6381 --network redis-net --mount type=bind,source=/home/debo/dockerData/redis/redis-6381.conf,target=/etc/redis.conf redis:4.0.14 redis-server /etc/redis.conf
docker run -d -p 6382:6379 --name redis-node-6382 --network redis-net --mount type=bind,source=/home/debo/dockerData/redis/redis-6382.conf,target=/etc/redis.conf redis:4.0.14 redis-server /etc/redis.conf

以上操作完成後,就將3個獨立的redis節點部署完成了。可以在宿主機(也就是自己電腦)命令行中執行命令redis-cli -p 6380看看是否部署成功

三、設置redis主從複製

以redis-node-6380作爲主節點,redis-node-6381和redis-node-6382作爲從節點,實現一主兩從架構。

  1. 運行命令docker network inspect redis-net會輸出如下信息
"Containers": {
            "1411e74f1619f6d4268fc0f9f70f89d9ba211729db49906cbc568d9f10c41ddc": {
                "Name": "redis-node-6382",
                "EndpointID": "0e3429f73ade0a9b972cf90fb5b4d299914cbafb1788f4c72aa00e6cf16a536f",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            },
            "74dbf13733caab38979141899dad954a3b64e9674b78e1378160cbdea203343f": {
                "Name": "redis-node-6381",
                "EndpointID": "c87bc4327a7fc471339ce04d465133745c460a70304854d33ec760df8e7ad7c6",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "9e1230cfc3a79f7dfe01397f1f473a4d2809c7ebe909267fd7edd45472641c19": {
                "Name": "redis-node-6380",
                "EndpointID": "5121006f5c432723d764cf9b8a06b8db11b7f10d643a28ef9be0c48e959ea592",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        }

可見redis-node-6380節點的IP地址爲172.18.0.2
2. 修改redis-6381.conf和redis-6382.conf,設置從節點,要修改的配置如下:

slaveof 172.18.0.2 6379
  1. 重啓redis-node-6381和redis-node-6382兩個容器
docker restart redis-node-6381
docker restart redis-node-6382

完成以上步驟後,一主兩從的redis高可用架構就部署好了,但是當主節點掛掉以後,從節點提升爲主節點這動作不是自動完成的,需要我們手動去將其中一個從節點提升爲主節點,同時還需要修改調用方的主節點地址,這個太麻煩了,所以我們需要sentinel集羣,它可以在主節點掛掉以後自動將其中一個從節點提升爲主節點,當主節點恢復以後,自動將老的主節點設置爲新主節點的從節點,同時主節點地址對調用方透明。

四、部署sentinel集羣

  1. 在自己電腦上建一個文件夾,然後放一個sentinel-26380.conf配置文件,這個配置文件直接拷貝的默認的sentinel.conf配置文件,只需修改如下兩個配置:
protected-mode no
sentinel monitor mymaster 172.18.0.2 6379 2
  1. 在命令行運行以下命令,用來在docker容器中啓動一個sentinel節點
docker run -d -p 26380:26379 --name sentinel-node-26380 --network redis-net --mount type=bind,source=/home/debo/dockerData/redis/sentinel-26380.conf,target=/etc/sentinel.conf redis:4.0.14 redis-sentinel /etc/sentinel.conf
  1. 將sentinel-26380.conf文件複製兩份,分別重命名爲sentinel-26381.conf和sentinel-26382.conf,然後依次執行如下命令,完成另外兩個sentinel節點的部署
docker run -d -p 26381:26379 --name sentinel-node-26381 --network redis-net --mount type=bind,source=/home/debo/dockerData/redis/sentinel-26381.conf,target=/etc/sentinel.conf redis:4.0.14 redis-sentinel /etc/sentinel.conf
docker run -d -p 26382:26379 --name sentinel-node-26382 --network redis-net --mount type=bind,source=/home/debo/dockerData/redis/sentinel-26382.conf,target=/etc/sentinel.conf redis:4.0.14 redis-sentinel /etc/sentinel.conf

以上操作完成後,含有三個節點的sentinel集羣就部署完成了

五、使用Jedis連接sentinel集羣進行驗證

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

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

/**
 * @author debo
 * @date 2020-01-03
 */
public class SentinelTest {
    public static void main(String[] args) {
        String masterName = "mymaster";
        // sentinel地址集合
        Set<String> addresses = new HashSet<>();
        addresses.add("localhost:26380");
        addresses.add("localhost:26381");
        addresses.add("localhost:26382");
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, addresses);
        Jedis jedis = jedisSentinelPool.getResource();
        jedis.set("testkey", "123321");
        System.out.println();
    }
}

可以發現,每次的jedis使用的都是主節點,當我們將主節點容器停止後,過一會兒再運行這例子,發現jedis使用的是新的主節點。(JedisSentinelPool中每次拿到的都是主節點連接,無法拿到從節點連接,如果要拿從節點信息,可以自己擴展)

六、sentinel集羣監控多組redis主從節點

sentinel集羣可以監控多組redis主從節點,假設現在要增加監控另一組redis主從節點,只需要將另一組的redis主節點信息添加到sentinel配置文件中即可,如:

sentinel monitor mymaster 172.18.0.2 6379 2
sentinel monitor mymaster1 172.18.0.5 6379 2

相應地,業務代碼中如果要同時使用兩組主從節點,那麼代碼可以調整如下:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

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

/**
 * @author debo
 * @date 2020-01-03
 */
public class SentinelTest {
    public static void main(String[] args) {
        String masterName = "mymaster";
        String master1Name = "mymaster1";
        // sentinel地址集合
        Set<String> addresses = new HashSet<>();
        addresses.add("localhost:26380");
        addresses.add("localhost:26381");
        addresses.add("localhost:26382");
        // 監控第一組redis主從節點
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, addresses);
        Jedis jedis = jedisSentinelPool.getResource();
        jedis.set("first", "123321");
        System.out.println();

        // 監控第二組redis主從節點
        JedisSentinelPool jedisSentinelPool1 = new JedisSentinelPool(master1Name, addresses);
        Jedis jedis1 = jedisSentinelPool1.getResource();
        jedis1.set("second", "123321");
        System.out.println();
    }
}

需要說明的是,受sentinel集羣監控的這兩組redis主從節點是相互獨立的,互不影響(不同於redis分片集羣)。

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