阿里云上Docker的Redis部署实战

360 阅读7分钟

公司的Redis服务基本都是由中间件团队或DBA提供的,最近在面试的过程中发现被问到这部分知识的时候比较生疏,所以打算自己搭建一下各种部署模式的Redis,加深自己的理解。 Redis主要包含单机(standalone),哨兵(Sentinel),集群(Cluster)三种部署方案。其中单机模式由于存在单点问题且无法自动故障恢复,不推荐使用于生产环境。

以下操作步骤全部经过实际操作验证

1. Docker环境准备

可参考阿里云官方说明:developer.aliyun.com/article/766…

   1. 安装Docker   docker yum install docker 
   2. 设置镜像站地址 vi /etc/docker/daemon.json
   {"registry-mirrors": "https://registry.docker-cn.com","live-restore":true}
   
   /** 其他下面可能用到的docker命令 **/
     docker ps // 查看所有正在运行容器
     docker stop [containerId] // containerId是容器的ID
     docker rm [containerId]  / remove删除所有容器
     docker ps -a // 查看所有容器
     docker ps -a -q // 查看所有容器ID
     docker run // 启动运行容器
     docker logs [containerId] // run异常时可以查看到异常日志
     docker exec -it [containerId] cmd //在指定容器中执行某个命令
     docker inspect [containerId] // 查看容器基本信息[查看容器ip] 

2. Redis主从模式(一主两从)

2.1 安装部署

首先通过部署给主节点添加2个从节点。根据实际情况看,主节点启动时并不关心从节点对应的配置信息。而为了保证记录的持久性,从节点一般持久化存储主节点的地址信息。但是由于这种方式无法自动主从切换,故生产不推荐使用。

    1. docker pull redis //下载镜像
    2. mkdir -p /mydata/redis/conf //创建redis配置目录
    3. 创建配置文件
       touch /mydata/redis/redis_master.conf
       touch /mydata/redis/redis_slave1.conf
       touch /mydata/redis/redis_slave2.conf
    4. 运行一主两从
       docker run -p 6379:6379 --name redis_master -v /mydata/redis/conf/redis_master.conf:/etc/redis/redis.conf -v /mydata/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
       docker run -p 6380:6379 --name redis_salve1 -v /mydata/redis/conf/redis_slave1.conf:/etc/redis/redis.conf -v /mydata/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes 
       docker run -p 6381:6379 --name redis_salve2 -v /mydata/redis/conf/redis_slave2.conf:/etc/redis/redis.conf -v /mydata/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes  
   
   /** 命令详解 **/
      -p 6379:6379 端口映射(主机端口:容器端口)
      --name redis_master 指定该容器别名
      -v 挂载目录 (主机目录:容器目录)
      -d redis 表示后台启动redis
      redis-server /etc/redis/redis.conf 以配置文件启动redis,加载容器内的conf文件,最终找到的是挂载的目录/etc/redis/redis.conf
      appendonly yes 开启redis 持久化

简易配置文件如下,若需要外网访问docker哨兵获取节点信息,此处ip需配置为公网ip,否则会出现连接哨兵后拿到虚拟节点ip的情况。

    /** redis_master.conf,内容参考如下 **/
    slave-announce-ip 12*.5*.6*.**8
    slave-announce-port 6379
    
    /** redis_slave1.conf,内容参考如下 **/
    slaveof 172.17.0.2 6379           //仅从节点需要该行
    slave-announce-ip 12*.5*.6*.**8   //外部暴露ip
    slave-announce-port 6380          //外部暴露端口
    
    /** redis_slave2.conf,内容参考如下 **/
    slaveof 172.17.0.2 6379          
    slave-announce-ip 12*.5*.6*.**8
    slave-announce-port 6381

2.2 验证过程

完成部署后,可以通过基础的get set命令进行简单验证,本处不提供代码验证过程,可以参考3.2哨兵模式的代码验证。此外,通过master节点的info看到信息如下:

...
# Replication
role:master
connected_slaves:2
slave0:ip=12*.5*.6*.**8,port=6380,state=online,offset=1975,lag=0
slave1:ip=12*.5*.6*.**8,port=6381,state=online,offset=1975,lag=0
...

3. Redis哨兵模式(Sentinel)

由于主从模式无法自动故障切换,所以Redis官方推荐使用哨兵模式做为高可用部署方案。该方案通过引入哨兵节点来监控并在异常时进行主从切换。哨兵模式其他相关资料可以参考官网说明:redisdoc.com/topic/senti… image.png

3.1 安装部署

   1. touch /mydata/redis/conf/sentinel.conf
   2. 运行哨兵节点实例
      docker run -d -p 26379:26379 --name redis_sentinel1 -v /mydata/redis/conf/sentinel.conf:/etc/redis/sentinel.conf redis
      docker run -d -p 26380:26379 --name redis_sentinel2 -v /mydata/redis/conf/sentinel.conf:/etc/redis/sentinel.conf redis
      docker run -d -p 26381:26379 --name redis_sentinel3 -v /mydata/redis/conf/sentinel.conf:/etc/redis/sentinel.conf redis
   3. 开启实例哨兵模式
      docker exec -itd redis_sentinel1 redis-sentinel /etc/redis/sentinel.conf
      docker exec -itd redis_sentinel2 redis-sentinel /etc/redis/sentinel.conf
      docker exec -itd redis_sentinel3 redis-sentinel /etc/redis/sentinel.conf

sentinel.conf,内容参考如下

port 26379
daemonize no
dir "/data"
sentinel monitor redis_master 12*.5*.6*.**8 6379 1
sentinel down-after-milliseconds redis_master 5000
sentinel failover-timeout redis_master 9000
sentinel parallel-syncs redis_master 1

部署完成后运行进程如下图: image.png

3.2 验证过程

登录哨兵节点查看状态信息的操作如下,哨兵是一个主节点配置的查询中心,并不是代理。当sentinel检查到故障转移时会通知业务方切换新的主节点配置。

docker exec -it redis_sentinel1 bash    //进入容器
redis-cli -h 127.0.0.1 -p 26379         //登录
sentinel master redis_master            //查看哨兵对应所有主节点
sentinel slaves redis_master            //查看某个节点对应的从节点
sentinel get-master-addr-by-name redis_master  //查看某个节点对应的ip:port

验证代码(JAVA):

    public static void main(String[] args) throws Exception{
        String masterName = "redis_master";
        Set<String> sentinels = new HashSet<>();
        sentinels.add("12*.5*.6*.**8:26379");
        sentinels.add("12*.5*.6*.**8:26380");
        sentinels.add("12*.5*.6*.**8:26381");
        JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels);
        //打印master节点
        System.out.println("IP:" + pool.getCurrentHostMaster());
        Jedis jedis = pool.getResource();
        System.out.println("VAL:" + jedis.get("yoojoy"));
        jedis.set("yoojoy", "value1");
        pool.close();
    }
  1. 运行上述代码,可验证通过连接哨兵节点获取redis节点的运行情况并取得master信息。
  2. 当我们后台docker stop redis_master后,程序正常运行,打印出的hostMaster节点已自动切换至slave节点,证明主从切换自动开启。
  3. 当我们后台docker start redis_master后,原主节点自动成为新主节点的slave节点。

4. Redis集群模式(Cluster)

src=http---5b0988e595225.cdn.sohucs.com-images-20180814-499dc2d0599a422c8dc6417d483ccaa8.png&refer=http---5b0988e595225.cdn.sohucs.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg.jpeg 在哨兵模式中,仍然只有一个Master节点。由于哨兵模式下,仅有master节点拥有写能力,当并发写请求较大时,哨兵模式并不能缓解写压力。而单一Redis节点并发在10W+,当更高的并发写时,单点问题就凸显出来了。此时便引入了集群模式的部署方案,部署架构图如上所示。

  1. 该方案实现了完全自治,故障转移无需引入哨兵节点,去中心化
  2. 多master节点通过哈希槽分片策略,能够相对均匀的分担数据量及请求并发量
  3. 节点间两两互联,组成分布式网络集群
  4. 每个master节点与他的从节点之间遵从主从模式模式特性

4.1 安装部署

(1) 安装redis-node

docker run -d --name redis-node1 -p 7001:6379 -p 17001:16379 redis --cluster-enabled yes
docker run -d --name redis-node2 -p 7002:6379 -p 17002:16379 redis --cluster-enabled yes
docker run -d --name redis-node3 -p 7003:6379 -p 17003:16379 redis --cluster-enabled yes
docker run -d --name redis-node4 -p 7004:6379 -p 17004:16379 redis --cluster-enabled yes
docker run -d --name redis-node5 -p 7005:6379 -p 17005:16379 redis --cluster-enabled yes
docker run -d --name redis-node6 -p 7006:6379 -p 17006:16379 redis --cluster-enabled yes

(2) 运行集群

docker exec -it redis-node1 /bin/bash
redis-cli --cluster create 12*.5*.6*.**8:7001 12*.5*.6*.**8:7002 12*.5*.6*.**8:7003 12*.5*.6*.**8:7004 12*.5*.6*.**8:7005 12*.5*.6*.**8:7006 --cluster-replicas 1

(3) 遇到问题

 由于6个节点都是运行在宿主机的docker容器中,相互之间需要通过公网地址基于gossip协议10000+port进行tcp通信,交换集群元数据信息。
 但是我的节点运行起来后,这部分通信异常。故而基于docker搭建redis cluster暂先停下。

4.2 验证过程

暂无