公司的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…
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
部署完成后运行进程如下图:
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();
}
- 运行上述代码,可验证通过连接哨兵节点获取redis节点的运行情况并取得master信息。
- 当我们后台docker stop redis_master后,程序正常运行,打印出的hostMaster节点已自动切换至slave节点,证明主从切换自动开启。
- 当我们后台docker start redis_master后,原主节点自动成为新主节点的slave节点。
4. Redis集群模式(Cluster)
在哨兵模式中,仍然只有一个Master节点。由于哨兵模式下,仅有master节点拥有写能力,当并发写请求较大时,哨兵模式并不能缓解写压力。而单一Redis节点并发在10W+,当更高的并发写时,单点问题就凸显出来了。此时便引入了集群模式的部署方案,部署架构图如上所示。
- 该方案实现了完全自治,故障转移无需引入哨兵节点,去中心化
- 多master节点通过哈希槽分片策略,能够相对均匀的分担数据量及请求并发量
- 节点间两两互联,组成分布式网络集群
- 每个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 验证过程
暂无