redis 哨兵模式

本示例基于 Centos 7,在阿里云的三台机器上部署 redis 集群,假设目前使用的账号为 release,拥有 sudo 权限。

由于 Docker 官方镜像下载较慢,可以开启阿里云的 Docker 镜像下载加速器,可参考此文进行配置。

假设三台主机的 ip 分别为:

  1. 主机一:192.168.0.1
  2. 主机二:192.168.0.2
  3. 主机三:192.168.0.3

三台主机的安装步骤相似,以主机一为例:

  1. 安装 docker 服务:
    sudo yum install -y docker
  1. 启动 docker 服务:
    sudo service docker start
  1. 查找 redis 镜像:
    sudo docker search redis
  1. 下载官方 redis 镜像:
    sudo  docker pull docker.io/redis
  1. 下载完后可检查镜像:
    sudo docker images 
  1. 主机上建立挂载目录和 redis 配置文件:
    mkdir -p /data/redis_data
    cd /data/redis_data
    touch redis.conf
    vi redis.conf

主机一上的 redis.conf 配置信息如下:

logfile "redis.log"
port 6379
dir /data
appendonly yes
appendfilename appendonly.aof
requirepass 1234

主机二、三上也同样建立挂载目录和 redis 配置文件,其内容稍有不同:

logfile "redis.log"
port 6379
dir /data
appendonly yes
appendfilename appendonly.aof
slaveof 192.168.0.1 6389
masterauth 1234
requirepass 1234

配置说明:

dir:工作目录
logfile:日志文件在工作目录下
slaveof:指明为主机一的从机
requirepass:redis 客户端连接的认证密码,若不需要可不配置
masterauth:主从 redis 同步的认证密码,与连接密码同,若不需要可不用配置
appendonly:是否需要持久化,yes 为需要

  1. 三台主机上都启动容器:
    sudo docker run -p 6379:6379 -v /data/redis_data/:/data --name redis-6379 -d docker.io/redis redis-server redis.conf

命令说明:

-p 6379:6379 : 将容器的 6379 端口映射到主机的 6379 端口
-v /data/redis_data:/data : 将主机中目录 /data/redis_data 挂载到容器的 /data
--name redis-6379: 给出容器名称
-d: 后台运行
docker.io/redis: 镜像名称
redis-server redis.conf: redis 的启动命令,指定配置文件
经过这一步后,三台主机已经建立了主从关系。

  1. 查看容器运行情况:
    sudo docker ps -a

运行中的容器,其状态为 Up,

若要停止并删除容器,其命令为:

sudo docker stop 容器id
sudo docker rm 容器id 
  1. 观察容器内部 redis 的情况:
    sudo docker exec -it 容器id /bin/bash

该命令可进入容器内部,其默认的工作目录即为 /data,再执行 redis-cli 命令,观察 redis 信息:

[release@sh-lbs02 6389-sentinel]$ sudo docker exec -it cac /bin/bash
root@cac589144cfd:/data# redis-cli
127.0.0.1:6379> info
NOAUTH Authentication required.
127.0.0.1:6379> auth SVKFGKPaFT
OK
127.0.0.1:6379> info
# Server
...
# Replication
role:slave
master_host:192.168.0.1
master_port:6379
...

至此,可确认三台主机的主从模式已经建立成功。

  1. 主机上建立哨兵目录和其配置文件:
cd /data/redis_data
touch sentinel.conf
vi sentinel.conf

三台主机上 sentinel.conf 的内容相同,如下:

logfile "sentinel.log"
sentinel monitor mymaster 192.168.0.1 6379 1
sentinel auth-pass mymaster 1234

配置说明:

  logfile "sentinel.log":输出日志目录
  sentinel monitor mymaster 192.168.0.1 6379 1:哨兵监控的主服务器名称为 mymaster,ip 为 192.168.0.1,端口为 6379,将这个主服务器标记为失效至少需要 1 个哨兵进程的同意
  sentinel auth-pass mymaster 1234 : 哨兵的认证密码

  1. 三台主机上启动哨兵模式:
sudo docker run -p 26379:26379 -v /data/redis_data/:/data --name redis-26379 -d docker.io/redis redis-sentinel sentinel.conf

命令说明:

-p 26379:26379 : 将容器的 26379 端口映射到主机的 26379 端口
-v /data/redis_data:/data : 将主机中目录 /data/redis_data 挂载到容器的 /data
--name redis-26379: 给出容器名称
-d: 后台运行
docker.io/redis: 镜像名称
redis-sentinel sentinel.conf: sentinel 的启动命令,指定配置文件

经过这一步后,哨兵模式已经建立起来。可通过观察日志查看启动情况

  1. 观察容器内哨兵情况:
    sudo docker exec -it 容器id /bin/bash

该命令可进入哨兵容器内部,其默认的工作目录即为 /data,再执行 redis-cli 命令,观察 redis 信息:

[release@sh-lbs02 6389-sentinel]$ sudo docker exec -it 25 /bin/bash
root@259da4458937:/data# redis-cli -h 127.0.0.1 -p 26379
127.0.0.1:26379> info
# Server
...
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.1:6379,slaves=2,sentinels=4
127.0.0.1:26379> 

至此,可以确定哨兵模式已启动成功。

Java 代码

        <!--redis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisSentinelPool;

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

//@SpringBootApplication
public class RedisApplication {

    private static JedisCluster jedisCluster = null;
    private static Set<HostAndPort> hostAndPorts = null;

    public static void main(String[] args) {
        //SpringApplication.run(RedisApplication.class, args);
        Set<String> sentinels = new HashSet<String>();
        String hostAndPort1 = "10.168.1.243:26379";
        String hostAndPort2 = "10.168.1.244:26379";
        String hostAndPort3 = "10.168.1.145:26379";
        sentinels.add(hostAndPort1);
        sentinels.add(hostAndPort2);
        sentinels.add(hostAndPort3);

        String clusterName = "mymaster";
        String password = "1234";

        JedisSentinelPool redisSentinelJedisPool = new JedisSentinelPool(clusterName, sentinels, password);

        Jedis jedis = null;
        try {
            jedis = redisSentinelJedisPool.getResource();
            System.out.println(jedis.get("name"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisSentinelJedisPool.returnBrokenResource(jedis);
        }

        redisSentinelJedisPool.close();
    }


}

Docker 应用系列(一)| 构建 Redis 哨兵集群 - 可可心心 - 博客园