典型的redis集群为:一主两从三哨兵。下面将以此架构搭建redis集群

Docker搭建Redis集群

常用的docker指令

docker search redis            //查询镜像
docker pull redis                //拉取官方镜像
docker images                        //查看镜像

配置主从

和mysql一样,redis也可以配置主从多节点,比如一主两从,master接收读写命令请求,两个slave从主节点同步复制数据,并且接收客户端的读请求,以分担master节点压力。(

配置主节点

(1)redis的挂载目录,我们确定在/Users/wangsiting/docker/redis下,配置一主两从,6379是主节点端口,6380和6381是从节点。

mkdir -p /Users/wangsiting/docker/redis
cd /Users/wangsiting/docker/redis
mkdir -p 6379 6380 6381
vi /Users/wangsiting/docker/redis/6379/redis.conf

(2)配置redis配置文件redis.conf

port 6379
#指明日志文件名
logfile "redis.log"        
#工作目录,数据库会写到这个目录下
dir /data                            
#纯累加模式,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件
appendonly yes                
appendfilename appendonly.aof        
#要求客户端在处理任何命令时都要验证身份和密码
requirepass 1234            

更多配置信息详见https://www.cnblogs.com/xuliangxing/p/7151685.html

(3)创建主节点容器

# 创建自定义网段
docker network create --subnet=172.18.0.0/16 redisnetwork

# 创建主节点容器
docker run -p 6379:6379 -v /Users/wangsiting/docker/redis/6379/redis.conf:/etc/redis/redis.conf -v /Users/wangsiting/docker/redis/6379:/data --name redismaster -d --net redisnetwork --ip 172.18.0.79 redis redis-server /etc/redis/redis.conf

# docker run:创建一个新的容器并运行一个命令
# -p:端口映射,容器内部的端口(后)映射到主机的高端口
# -v:挂载数据目录和配置文件(宿主机目录:容器内部目录)
# --name:指定容器名称
# -d:后台运行容器,并返回容器ID
# --net redisnetwork --ip 172.18.0.79:指定容器的iP
# redis-server:指明以该配置文件启动redis

配置从节点

(1)配置文件和上面类似,需要增加配置从节点的主节点

vi /Users/wangsiting/docker/redis/6380/redis.conf

## 配置文件内容
port 6380
logfile "redis.log"
dir /data
appendonly yes
appendfilename appendonly.aof
## 指定主节点的IP和端口号
slaveof 172.18.0.79 6379            
requirepass 1234
masterauth 1234

另外一个从节点6381类似

vi /Users/wangsiting/docker/redis/6381/redis.conf

## 配置文件内容
port 6381
logfile "redis.log"
dir /data
appendonly yes
appendfilename appendonly.aof
## 指定主节点的IP和端口号
slaveof 172.18.0.79 6379            
requirepass 1234
masterauth 1234

(2)创建两个从节点容器,名称为redisslave1和redisslave2

docker run -p 6380:6379 -v /Users/wangsiting/docker/redis/6380/redis.conf:/etc/redis/redis.conf -v /Users/wangsiting/docker/redis/6380:/data --name redisslave1 -d --net redisnetwork --ip 172.18.0.80 redis redis-server /etc/redis/redis.conf

docker run -p 6381:6379 -v /Users/wangsiting/docker/redis/6381/redis.conf:/etc/redis/redis.conf -v /Users/wangsiting/docker/redis/6381:/data --name redisslave2 -d --net redisnetwork --ip 172.18.0.81 redis redis-server /etc/redis/redis.conf

使用docker ps命令查看运行中的容器,可以看到三个节点已经正常运行

:如果没有某个节点不能正常启动,一般是配置文件出错,需要先用docker stop redisslave1 redisslave2 停止容器,然后先用docker rm redisslave1 redisslave2删除容器,再重新配置文件并启动容器

查看信息

如果3个节点都能正常启动,进入到主节点容器内部,查看复制状况

docker exec -it redismaster bash        //进入容器内部
redis-cli        //连接本地的redis服务
auth 1234        //输入密码
info replication        //查看复制状况

如果看到connected_slaves:2,并且下面显示两个从节点的ip端口、state=online后,就代表主从配置成功。

退出redis-cli的命令是先输入quit,然后输入exit。回到宿主机。

检查两个从节点6380和6381的info replication,这里以6380为例:

docker exec -it redisslave1 bash
redis-cli -p 6380
/data# redis-cli
127.0.0.1:6380> auth 1234
OK
127.0.0.1:6380> info replication

从节点配置成功应显示:role:slave、master_host和master_port都正确、master_link_status为up状态。另一个从节点也可如此检查。

此时,主从已经配置并检查确认成功,可以通过往redis主节点新增key看从节点是否有同步。(下载一个rdm客户端或者使用redis-cli控制台命令都可以新增or查看key)

我们用rdm客户端登录到主节点,host本机填127.0.0.1本地回环地址,远程主机填写公网ip

选择db0数据库,默认有16个库,右键新增key,reload库会发现多了一个key

用控制台命令分别连接两个从节点,去确认是否有和主节点同样的key

docker exec -it redisslave1 bash
/data# redis-cli -p 6380
127.0.0.1:6380> auth 1234
OK
127.0.0.1:6380> keys *

可以看出6380和6381,都有同样的key。这一步,主从同步可以确认成功,数据已经可以实现同步!

配置哨兵

哨兵可以在主发生故障后,自动进行故障转移,从从机里选出一台升级为主机,并持续监听着原来的主机,当原来的主机恢复后,会将其作为新主的从机。

(1)创建三个哨兵节点的目录

mkdir /Users/wangsiting/docker/redis/26379 /Users/wangsiting/docker/redis/26380 /Users/wangsiting/docker/redis/26381

(2)哨兵节点的配置文件

vi /Users/wangsiting/docker/redis/26379/sentinel.conf

port 23279
# 哨兵sentinel的工作目录
dir "/data"
logfile "sentinel.log"
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了  
# sentinel monitor <master-name> <ip> <redis-port> <quorum> 
sentinel monitor redismaster 172.18.0.79 6379 2
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒  
sentinel down-after-milliseconds redismaster 10000
# 故障转移的超时时间 failover-timeout 
sentinel failover-timeout redismaster 60000
sentinel auth-pass redismaster 1234

另外两个哨兵的配置与上类似

vi /Users/wangsiting/docker/redis/26380/sentinel.conf

port 23280
# 哨兵sentinel的工作目录
dir "/data"
logfile "sentinel.log"
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了  
# sentinel monitor <master-name> <ip> <redis-port> <quorum> 
sentinel monitor redismaster 172.18.0.79 6379 2
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒  
sentinel down-after-milliseconds redismaster 10000
# 故障转移的超时时间 failover-timeout 
sentinel failover-timeout redismaster 60000
sentinel auth-pass redismaster 1234

vi /Users/wangsiting/docker/redis/26381/sentinel.conf

port 23281
# 哨兵sentinel的工作目录
dir "/data"
logfile "sentinel.log"
# quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了  
# sentinel monitor <master-name> <ip> <redis-port> <quorum> 
sentinel monitor redismaster 172.18.0.79 6379 2
# 指定多少毫秒之后 主节点没有应答哨兵sentinel 此时 哨兵主观上认为主节点下线 默认30秒  
sentinel down-after-milliseconds redismaster 10000
# 故障转移的超时时间 failover-timeout 
sentinel failover-timeout redismaster 60000
sentinel auth-pass redismaster 1234

(3)创建3个哨兵节点的容器并启动

# 创建运行哨兵的容器,注哨兵容器的ip要和监视的redis节点处于同一网段
docker run -p 26379:26379 -v /Users/wangsiting/docker/redis/26379/sentinel.conf:/etc/redis/sentinel.conf -v /Users/wangsiting/docker/redis/26379:/data --name sentinel26379 -d --net redisnetwork --ip 172.18.16.79 redis redis-sentinel /etc/redis/sentinel.conf

docker run -p 26380:26380 -v /Users/wangsiting/docker/redis/26380/sentinel.conf:/etc/redis/sentinel.conf -v /Users/wangsiting/docker/redis/26380:/data --name sentinel26380 -d --net redisnetwork --ip 172.18.16.80 redis redis-sentinel /etc/redis/sentinel.conf

docker run -p 26381:26381 -v /Users/wangsiting/docker/redis/26381/sentinel.conf:/etc/redis/sentinel.conf -v /Users/wangsiting/docker/redis/26381:/data --name sentinel26381 -d --net redisnetwork --ip 172.18.16.81 redis redis-sentinel /etc/redis/sentinel.conf