查看redis官网,发现新版稳定为:redis6.0.10
先决条件:
服务器使用我的阿里云服务器:CentOS 7.6 64位
安装docker环境:https://blog.csdn.net/weixin_39816740/article/details/111172008
这里我们选择安装redis6.0.10
我们这里选择通过已有的镜像安装;
1.根据文章docker安装指定版本的tag镜像得到安装reids镜像的docker命令
docker pull redis:6.0.10
但是在操作docker时候出现Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
systemctl status docker 查看docker状态
docker处于运行状态,也是root用户操作的
(引用博客:docker出现Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon run)
查询解决办法一:docker服务没有启动,重新启动docker服务
https://blog.csdn.net/zxzxzxzx2121/article/details/61914870/
查询解决办法二:重新载入systemd,扫描新的或者变动的单元,然后重新启动docker服务
https://www.cnblogs.com/forturn/p/9371841.html
查询解决办法三:权限问题,使用root账户或者使用sudo 重新启动docker服务
https://segmentfault.com/q/1010000005040763
解决办法四:使用 -H 可以改变docker进程监听指定的IP和端口。默认情况下,docker会监听 unix:///var/run/docker.sock,只允许本地的root用户连接。
https://www.widuu.com/archives/01/947.html
从这里我们看到大致是要么用户没有权限或者是监听的端口不正确。
到这里我想起来咱的上一篇doker操作:docker中使用idea部署运行项目(项目以镜像方式运行)中设置证书时修改监听端口配置文件:
那我们把-H unix:///var/run/docker.sock追加监听查看docker配置信息
vim /usr/lib/systemd/system/docker.service
修改为:
保存退出刷新配置文件,并重启
systemctl daemon-reload
systemctl restart docker
systemctl status docker.service
验证是否可以了:
验证证书是否受到影响:
也没问题!
继续安装redis镜像
因为需要redis的配置文件,这里最好还是去redis的官方去下载一个redis使用里面的配置文件即可
这里把redis压缩包分享出来
链接:https://pan.baidu.com/s/1Leh_ZzE6Ln6A_0_tgu37JA
提取码:cb6t
在这里我们需要先规划一下redis的两个配置文件放的位置以及结构。我们都知道reids启动是通过配置文件启动的。我们这里要布置一主两从。那么·为了便于管理这些配置文件,在/opt目录下创建redis6.0.10文件夹,在此目录下创建6个文件夹,3个reids(redis1,redis2,redis3)3个sentinel(sentinel1,sentinel2,sentinel3);在这3个redis文件夹之下再分别创建3个文件夹data和conf,logs;在3个sentinel之下再分别创建conf,logs文件夹;
先搭建主从
对reids1,redis2,redis3的配置文件做出配置,在这里,我们指定redis1(端口6379)为master,redis2(端口6380),redis3(端口6381)为slave
将下载的redis压缩包解压复制其中的配置文件到reids1,redis2,redis3的conf目录下,分别配置:
reids1(6379):
# 注释这一行,表示Redis可以接受任意ip的连接
# bind 127.0.0.1
# 端口设置
port 6379
# 让redis服务后台运行
daemonize yes
# 设定密码(可选,如果这里开启了密码要求,slave的配置里就要加这个密码)
requirepass 主库设置的密码
# 设定主库的密码,用于认证,如果主库开启了requirepass选项这里就必须填相应的密码
masterauth 主库设置的密码
#redis以守护进程方式运行时,系统默认会把pid写入/var/run/redis.pid,可以通过pidfile指定pid文件
pidfile /var/run/redis_6379.pid
# redis启动后数据持久化
appendonly yes
#在docker中生成的日志文件路径
logfile /var/log/redis/redis.log
reids2(6380):
# 注释这一行,表示Redis可以接受任意ip的连接
# bind 127.0.0.1
# 端口设置
port 6380
# 让redis服务后台运行
daemonize yes
# 设定密码(可选,如果这里开启了密码要求,slave的配置里就要加这个密码)
requirepass 主库设置的密码
# 设定主库的密码,用于认证,如果主库开启了requirepass选项这里就必须填相应的密码
masterauth 主库设置的密码
# 设定master的IP和端口号,redis配置文件中的默认端口号是6379
# 低版本的redis这里会是slaveof,意思是一样的,因为slave是比较敏感的词汇,所以在redis后面的版本中不在使用slave的概念,取而代之的是replica
# 将端口号为6379做为主,其余两台机器做从。ip和端口号按照机器和配置做相应修改。
replicaof 容器redis-01的ip 6379
#redis以守护进程方式运行时,系统默认会把pid写入/var/run/redis.pid,可以通过pidfile指定pid文件
pidfile /var/run/redis_6380.pid
# redis启动后数据持久化
appendonly yes
#在docker中生成的日志文件路径
logfile /var/log/redis/redis.log
redis3(6381):
# 注释这一行,表示Redis可以接受任意ip的连接
# bind 127.0.0.1
# 端口设置
port 6381
# 让redis服务后台运行
daemonize yes
# 设定密码(可选,如果这里开启了密码要求,slave的配置里就要加这个密码)
requirepass 主库设置的密码
# 设定主库的密码,用于认证,如果主库开启了requirepass选项这里就必须填相应的密码
masterauth 主库设置的密码
# 设定master的IP和端口号,redis配置文件中的默认端口号是6379
# 低版本的redis这里会是slaveof,意思是一样的,因为slave是比较敏感的词汇,所以在redis后面的版本中不在使用slave的概念,取而代之的是replica
# 将端口号为6379做为主,其余两台机器做从。ip和端口号按照机器和配置做相应修改。
replicaof 容器redis-01的ip 6379
#redis以守护进程方式运行时,系统默认会把pid写入/var/run/redis.pid,可以通过pidfile指定pid文件
pidfile /var/run/redis_6381.pid
# redis启动后数据持久化
appendonly yes
#在docker中生成的日志文件路径
logfile /var/log/redis/redis.log
注意:如果replicaof 容器redis-01的ip 6379配置错误日志文件如下:
分别启动:
命令解释:
# 指定容器名字,后续可以通过名字进行容器管理
--name
# 后台运行容器,并返回容器ID
-d
# 把容器内的6379端口映射到宿主机6379端口
-p 6379:6379
# 把宿主机配置好的redis.conf放到容器内的这个位置中
-v /opt/redis6.0.10/redis1/conf/redis.conf:/usr/local/etc/redis/redis.conf
# 把redis持久化的数据在宿主机内显示,做数据备份
# 启动redis容器,持久化文件默认存在了data目录(dir ./)
-v /opt/redis6.0.10/redis1/data:/data
# 把redis日志数据在宿主机内显示
-v /opt/redis6.0.10/redis1/logs:/var/log/redis
# 这个是关键配置,让redis不是无配置启动,而是按照这个redis.conf的配置启动
redis-server /usr/local/etc/redis/redis.conf
redis1:
#首先以后台模式运行容器
docker run -it --name redis-01 -v /opt/redis6.0.10/redis1/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /opt/redis6.0.10/redis1/data:/data -d -p 6379:6379 -v /opt/redis6.0.10/redis1/logs:/var/log/redis redis:6.0.10 /bin/bash
#以交互模式进入容器
docker exec -it redis-01 bash
#启动redis服务器,如果没有任何输出,就说明成功了
redis-server /usr/local/etc/redis/redis.conf
# 在容器里启动一个redis客户端
redis-cli -h 127.0.0.1 -p 6379
# 认证输入密码
auth 设置的密码
# 执行info命令,查看服务器状态
info
# 如果是主,这里的role的值会是master,如果是从,这里的role的值会是slave
role:slave
# 对于slave,还要查看master_link_status这个属性值。slave上这个属性值为up就说明主从复制是OK的,否者就有问题。如果从机状态不为up,首先排查主机的端口是否被限,然后查看redis日志排查原因
master_link_status:up
...
# 最后退出容器
exit
我们就来看下reids-01容器的ip
docker inspect 容器名字 或者 docker inspect 容器id | grep IPAddress
可以看到我的reids-01的ip为:172.17.0.2
redis2:
#首先以后台模式运行容器
docker run -it --name redis-02 -v /opt/redis6.0.10/redis2/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /opt/redis6.0.10/redis2/data:/data -d -p 6380:6380 -v /opt/redis6.0.10/redis2/logs:/var/log/redis redis:6.0.10 /bin/bash
#以交互模式进入容器
docker exec -it redis-02 bash
#启动redis服务器,如果没有任何输出,就说明成功了
redis-server /usr/local/etc/redis/redis.conf
# 在容器里启动一个redis客户端(注意这里连接需要配置上ip和端口,不然会出现Could not connect to Redis at 127.0.0.1:6379: Connection refused)
redis-cli -h 127.0.0.1 -p 6380
# 认证输入密码
auth 设置的密码
# 执行info命令,查看服务器状态
info
# 如果是主,这里的role的值会是master,如果是从,这里的role的值会是slave
role:slave
# 对于slave,还要查看master_link_status这个属性值。slave上这个属性值为up就说明主从复制是OK的,否者就有问题。如果从机状态不为up,首先排查主机的端口是否被限,然后查看redis日志排查原因
master_link_status:up
...
# 最后退出容器
exit
redis3:
#首先以后台模式运行容器
docker run -it --name redis-03 -v /opt/redis6.0.10/redis3/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /opt/redis6.0.10/redis3/data:/data -d -p 6381:6381 -v /opt/redis6.0.10/redis3/logs:/var/log/redis redis:6.0.10 /bin/bash
#以交互模式进入容器
docker exec -it redis-03 bash
#启动redis服务器,如果没有任何输出,就说明成功了
redis-server /usr/local/etc/redis/redis.conf
# 在容器里启动一个redis客户端(注意这里连接需要配置上ip和端口,不然会出现Could not connect to Redis at 127.0.0.1:6379: Connection refused)
redis-cli -h 127.0.0.1 -p 6381
# 认证输入密码
auth 设置的密码
# 执行info命令,查看服务器状态
info
# 如果是主,这里的role的值会是master,如果是从,这里的role的值会是slave
role:slave
# 对于slave,还要查看master_link_status这个属性值。slave上这个属性值为up就说明主从复制是OK的,否者就有问题。如果从机状态不为up,首先排查主机的端口是否被限,然后查看redis日志排查原因
master_link_status:up
...
# 最后退出容器
exit
查看redis-01容器redis的info
验证主从复制
主从搭建成功后,可以通过在master上写入一个key-value值,查看是否会同步到slave上,来验证主从同步是否能成功。运行一个redis-cli,向test_key写入一个值
在任意slave机器上进入容器(redis-03),也运行一个redis-cli,查询这个key的值。如果能查询到这个值,且与主机上的值相同,说明主从同步成功。
经测试,主动同步成功。
搭建哨兵模式
主从结构搭建成功了,系统的可用性变高了,但是如果主发生故障,需要人工手动切换从机为主机。这种切换工作不仅浪费人力资源,更大的影响是主从切换期间这段时间redis是无法对外提供服务的。因此,哨兵系统被开发出来了,哨兵可以在主发生故障后,自动进行故障转移,从从机里选出一台升级为主机,并持续监听着原来的主机,当原来的主机恢复后,会将其作为新主的从机。
跟搭建redis一主两从相似。
先上传sentinel.conf到sentinel1,sentinel2,sentinel3的conf目录下;在这里,我们指定sentinel1(端口26379),sentinel2(端口26380),sentinel3(端口26381)
sentinel1(26379):
# 端口设置
port 26379
# 让sentinel服务后台运行
daemonize yes
#sentinel以守护进程方式运行时,系统默认会把pid写入/var/run/redis-sentinel.pid,可以通过pidfile指定pid文件(其实不设置也可以,因为在不同的容器中运行)
pidfile /var/run/sentinel_26379.pid
# 修改日志文件的路径(注意这里的路径是sentinel容器内部的路径)
logfile "/var/log/redis/sentinel.log"
# 修改监控的主redis服务器
# 最后一个2表示,两台机器判定主被动下线后,就进行failover(故障转移)
sentinel monitor mymaster 172.17.0.2 6379 2
redis服务器配置了密码连接,则要增加如下配置(注意这行配置要配置到 sentinel monitor mymaster ip port 后面,因为名称 mymaster要先定义):
sentinel auth-pass mymaster redis服务密码
sentinel2(26380):
# 端口设置
port 26380
# 让sentinel服务后台运行
daemonize yes
#sentinel以守护进程方式运行时,系统默认会把pid写入/var/run/redis-sentinel.pid,可以通过pidfile指定pid文件(其实不设置也可以,因为在不同的容器中运行)
pidfile /var/run/sentinel_26380.pid
# 修改日志文件的路径(注意这里的路径是sentinel容器内部的路径)
logfile "/var/log/redis/sentinel.log"
# 修改监控的主redis服务器
# 最后一个2表示,两台机器判定主被动下线后,就进行failover(故障转移)
sentinel monitor mymaster 172.17.0.2 6379 2
redis服务器配置了密码连接,则要增加如下配置(注意这行配置要配置到 sentinel monitor mymaster ip port 后面,因为名称 mymaster要先定义):
sentinel auth-pass mymaster redis服务密码
sentinel3(26381):
# 端口设置
port 26381
# 让sentinel服务后台运行
daemonize yes
#sentinel以守护进程方式运行时,系统默认会把pid写入/var/run/redis-sentinel.pid,可以通过pidfile指定pid文件(其实不设置也可以,因为在不同的容器中运行)
pidfile /var/run/sentinel_26381.pid
# 修改日志文件的路径(注意这里的路径是sentinel容器内部的路径)
logfile "/var/log/redis/sentinel.log"
# 修改监控的主redis服务器
# 最后一个2表示,两台机器判定主被动下线后,就进行failover(故障转移)
sentinel monitor mymaster 172.17.0.2 6379 2
redis服务器配置了密码连接,则要增加如下配置(注意这行配置要配置到 sentinel monitor mymaster ip port 后面,因为名称 mymaster要先定义):
sentinel auth-pass mymaster redis服务密码
分别启动:
命令解释:
# 指定容器名字,后续可以通过名字进行容器管理
--name
# 后台运行容器,并返回容器ID
-d
# 把容器内的26379端口映射到宿主机26379端口
-p 26379:26379
# 把宿主机配置好的sentinel.conf放到容器内的这个位置中
-v /opt/redis6.0.10/sentinel1/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf
# 把redis日志数据在宿主机内显示
-v /opt/redis6.0.10/sentinel1/logs:/var/log/redis
# 启动哨兵
redis-sentinel /usr/local/etc/redis/sentinel.conf
sentinel1(26379)启动:
#首先以后台模式运行容器
docker run -it --name sentinel-01 -p 26379:26379 -v /opt/redis6.0.10/sentinel1/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf -v /opt/redis6.0.10/sentinel1/logs:/var/log/redis -d redis:6.0.10 /bin/bash
# 进入容器
docker exec -it sentinel-01 bash
# 启动哨兵
redis-sentinel /usr/local/etc/redis/sentinel.conf
# 连接redis-cli 查看redis连接状态
redis-cli -p 26379
#执行如下命令,查看redis主信息
sentinel master mymaster
#执行如下命令,查看从redis信息是否正常
sentinel slaves mymaster
# 查看日志,哨兵成功监听到一主和两从的机器(容器内部日志文件)
cat /var/log/redis/sentinel.log
sentinel2(26380)启动:
#首先以后台模式运行容器
docker run -it --name sentinel-02 -p 26380:26380 -v /opt/redis6.0.10/sentinel2/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf -v /opt/redis6.0.10/sentinel2/logs:/var/log/redis -d redis:6.0.10 /bin/bash
# 进入容器
docker exec -it sentinel-02 bash
# 启动哨兵
redis-sentinel /usr/local/etc/redis/sentinel.conf
# 连接redis-cli 查看redis连接状态
redis-cli -p 26380
#执行如下命令,查看redis主信息
sentinel master mymaster
#执行如下命令,查看从redis信息是否正常
sentinel slaves mymaster
# 查看日志,哨兵成功监听到一主和两从的机器(容器内部日志文件)
cat /var/log/redis/sentinel.log
sentinel3(26381)启动:
#首先以后台模式运行容器
docker run -it --name sentinel-03 -p 26381:26381 -v /opt/redis6.0.10/sentinel3/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf -v /opt/redis6.0.10/sentinel3/logs:/var/log/redis -d redis:6.0.10 /bin/bash
# 进入容器
docker exec -it sentinel-03 bash
# 启动哨兵
redis-sentinel /usr/local/etc/redis/sentinel.conf
# 连接redis-cli 查看redis连接状态
redis-cli -p 26381
#执行如下命令,查看redis主信息
sentinel master mymaster
#执行如下命令,查看从redis信息是否正常
sentinel slaves mymaster
# 查看日志,哨兵成功监听到一主和两从的机器(容器内部日志文件)
cat /var/log/redis/sentinel.log
验证failover(故障转移)
为了验证哨兵机制下的自动主从切换,我们将redis-01的redis进程kill掉。(停掉容器也可以使用容器对应的NAMES来停掉)
查看redis-sentinel日志(sentinel-01的日志我们和/opt/redis6.0.10/sentinel1/logs/sentinel.log做了链接,查看这个即可)
我们可以进入redis-03容器查看info
成功!如有其他不同意见请指出。
补充(参考):
故障转移是由 sentinel 领导者节点来完成的(只需要一个sentinel节点),关于 sentinel 领导者节点的选取也是每个 sentinel 向其他 sentinel 节点发送我要成为领导者的命令,超过半数sentinel 节点同意,并且也大于quorum ,那么他将成为领导者,如果有多个sentinel都成为了领导者,则会过段时间在进行选举.
sentinel 领导者节点选举出来后,会通过如下几步进行故障转移:
一.从 slave 节点中选出一个合适的 节点作为新的master节点.这里的合适包括如下几点:
1.选择 slave-priority(slave节点优先级)最高的slave节点,如果存在则返回,不存在则继续下一步判断.
2.选择复制偏移量最大的 slave 节点(复制的最完整),如果存在则返回,不存在则继续.
3.选择runId最小的slave节点(启动最早的节点)
二.对上面选出来的 slave 节点执行 slaveof no one 命令让其成为新的 master 节点.
三.向剩余的 slave 节点发送命令,让他们成为新master 节点的 slave 节点,复制规则和前面设置的 parallel-syncs 参数有关.
四.更新原来master 节点配置为 slave 节点,并保持对其进行关注,一旦这个节点重新恢复正常后,会命令它去复制新的master节点信息.(注意:原来的master节点恢复后是作为slave的角色)
可以从 sentinel 日志中出现的几个消息来进行查看故障转移:
1.+switch-master:表示切换主节点(从节点晋升为主节点)
2.+sdown:主观下线
3.+odown:客观下线
4.+convert-to-slave:切换从节点(原主节点降为从节点)