实战之部署Redis哨兵模式-Docker版本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实战之部署Redis哨兵模式-Docker版本相关的知识,希望对你有一定的参考价值。
参考技术A 前提创建好集群所需要的配置文件分开文件夹来写可以这样创建号网络
创建主节点
主节点的配置文件 可直接复制,要加啥自己加
子节点
子节点
参数重点
/home/docker/redis6380为宿主机的地址也就是你阿里云服务器放redis.conf的路径
--network myredis 为你上面创建的网络的名字
启动好了之后主从复制就好了你可以测测
接下来配置哨兵模式的配置文件
每个容器下面写入sentinel.conf内容为
写完后输入
后台启动就好了
ps -ef 查看是否后台启动
Redis主从加哨兵模式集群部署
目录
1 Redis版本特性介绍
这里安装6个redis,配置如下:
小知识点(Redis6.0.5):
如果需要安装单机版,需要安装指定的插件
yum -y install gcc gcc-c++ libstdc++-devel
升级gcc
yum -y install centos-release-scl devtoolset-7
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
切换gcc7
scl enable devtoolset-7 bash
单机版安装
解压redis-6.0.5.tar.gz
tar -xf redis-6.0.5.tar.gz
进入到redis-6.0.5目录
cd redis-6.0.5
编译安装
make
make install PREFIX=/usr/local/server/redis-cluster/redis
redis.conf拷贝到安装bin目录下
cp /usr/local/server/redis-cluster/redis-6.0.5/redis.conf /usr/local/server/redis-
cluster/redis/bin/
修改redis.conf更改redis配置:
设置daemonize为yes 让redis支持后台启动
将protected-mode 改为no,远程连接就不需要账号密码了
bind 192.168.211.141
注意安装Redis6.x的时候一定要切换到gcc7再安装,否则会报如下错误:
切换语法:
scl enable devtoolset-7 bash
Redis我们采用Redis6.0.5最新版本,它有很多新特性,我们这里对Redis每个版本的特性介绍一下:
Redis2.6
Redis2.6在2012年正是发布,经历了17个版本,到2.6.17版本,相对于Redis2.4,主要特性如下:
1)服务端支持Lua脚本。
2)去掉虚拟内存相关功能。
3)放开对客户端连接数的硬编码限制。
4)键的过期时间支持毫秒。
5)从节点支持只读功能。
6)两个新的位图命令:bitcount和bitop。
7)增强了redis-benchmark的功能:支持定制化的压测,CSV输出等功能。
8)基于浮点数自增命令:incrbyfloat和hincrbyfloat。
9)redis-cli可以使用–eval参数实现Lua脚本执行。
10)shutdown命令增强。
11)重构了大量的核心代码,所有集群相关的代码都去掉了,cluster功能将会是3.0版本最大的亮点。
12)info可以按照section输出,并且添加了一些统计项
13)sort命令优化
Redis2.8
Redis2.8在2013年11月22日正式发布,经历了24个版本,到2.8.24版本,相比于Redis2.6,主要特性如下:
1)添加部分主从复制的功能,在一定程度上降低了由于网络问题,造成频繁全量复制生成RDB对系统造成的压力。
2)尝试性的支持IPv6.
3)可以通过config set命令设置maxclients。
4)可以用bind命令绑定多个IP地址。
5)Redis设置了明显的进程名,方便使用ps命令查看系统进程。
6)config rewrite命令可以将config set持久化到Redis配置文件中。
7)发布订阅添加了pubsub。
8)Redis Sentinel第二版,相比于Redis2.6的Redis Sentinel,此版本已经变成生产可用。
Redis3.0(里程碑)
Redis3.0在2015年4月1日正式发布,相比于Redis2.8主要特性如下:
Redis最大的改动就是添加Redis的分布式实现Redis Cluster。
1)Redis Cluster:Redis的官方分布式实现。
2)全新的embedded string对象编码结果,优化小对象内存访问,在特定的工作负载下载速度大幅提升。
3)Iru算法大幅提升。
4)migrate连接缓存,大幅提升键迁移的速度。
5)migrate命令两个新的参数copy和replace。
6)新的client pause命令,在指定时间内停止处理客户端请求。
7)bitcount命令性能提升。
8)cinfig set设置maxmemory时候可以设置不同的单位(之前只能是字节)。
9)Redis日志小做调整:日志中会反应当前实例的角色(master或者slave)。
10)incr命令性能提升。
Redis3.2
Redis3.2在2016年5月6日正式发布,相比于Redis3.0主要特征如下:
1)添加GEO相关功能。
2)SDS在速度和节省空间上都做了优化。
3)支持用upstart或者systemd管理Redis进程。
4)新的List编码类型:quicklist。
5)从节点读取过期数据保证一致性。
6)添加了hstrlen命令。
7)增强了debug命令,支持了更多的参数。
8)Lua脚本功能增强。
9)添加了Lua Debugger。
10)config set 支持更多的配置参数。
11)优化了Redis崩溃后的相关报告。
12)新的RDB格式,但是仍然兼容旧的RDB。
13)加速RDB的加载速度。
14)spop命令支持个数参数。
15)cluster nodes命令得到加速。
16)Jemalloc更新到4.0.3版本。
Redis4.0
可能出乎很多的意料,Redis3.2之后的版本是4.0,而不是3.4、3.6、3.8。
一般这种重大版本号的升级也意味着软件或者工具本身发生了重大改革。下面是Redis4.0的新特性:
1)提供了模块系统,方便第三方开发者拓展Redis的功能。
2)PSYNC2.0:优化了之前版本中,主从节点切换必然引起全量复制的问题。
3)提供了新的缓存剔除算法:LFU(Last Frequently Used),并对已有算法进行了优化。
4)提供了非阻塞del和flushall/flushdb功能,有效解决删除了bigkey可能造成的Redis阻塞。
5)提供了memory命令,实现对内存更为全面的监控统计。
6)提供了交互数据库功能,实现Redis内部数据库的数据置换。
7)提供了RDB-AOF混合持久化格式,充分利用了AOF和RDB各自优势。
8)Redis Cluster 兼容NAT和Docker。
Redis5.0
1.新的Stream数据类型。5.0
2.新的Redis模块API:Timers and Cluster API。
3. RDB现在存储LFU和LRU信息。
4.集群管理器从Ruby(redis-trib.rb)移植到C代码。可以在redis-cli中。查看redis-cli —cluster help
了解
更多信息。
5.新sorted set命令:ZPOPMIN / MAX和阻塞变量。
6.主动碎片整理V2。
7.增强HyperLogLog实现。
8.更好的内存统计报告。
9.许多带有子命令的命令现在都有一个HELP子命令。
10.客户经常连接和断开连接时性能更好。
11.错误修复和改进。
12. Jemalloc升级到5.1版
Redis6.0.5(里程碑)
1.ACL用户权限控制功能
2.RESP3:新的 Redis 通信协议
3.Cluster 管理工具
4.SSL 支持
5.IO多线程支持
6.新的Module API
7.新的 Expire 算法
8.Redis Cluster Proxy
9.Disque
2 Redis集群配置
现在安装对应的应用软件一般都推荐使用Docker容器,我们这里也不例外,直接使用Docker容器进行安装,安装大
概要分这几个步骤:
1、创建redis-cluster.tmpl配置Redis信息【端口、是否开启集群等】
2、创建redis.sh配置需要创建的redis信息
3、添加网络,redis集群使用该网络
4、执行redis.sh实现创建redis
5、执行redis-cli创建集群
配置Redis信息
创建 redis-cluster.tmpl 配置Redis信息(redis.conf)
#端口
port $PORT
#非保护模式
protected-mode no
#启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
#超时时间
cluster-node-timeout 5000
#集群各节点IP地址
cluster-announce-ip 192.168.211.141
#集群节点映射端口
cluster-announce-port $PORT
#集群总线端口
cluster-announce-bus-port 1$PORT
#开启aof持久化策略
appendonly yes
#后台运行
#daemonize yes
#进程号存储
pidfile /var/run/redis_$PORT.pid
#集群加密
#masterauth itheima
#requirepass itheima
Redis创建配置
创建 redis.sh 配置需要创建的 Redis 集群
#!/bin/bash
#在/usr/local/server/redis-cluster下生成conf和data目标,并生成配置信息
for port in `seq 7001 7006`;
do
mkdir -p ./$port/conf && PORT=$port envsubst < ./redis-cluster.tmpl >
./$port/conf/redis.conf && mkdir -p ./$port/data;
done
#创建6个redis容器
for port in `seq 7001 7006`;
do
docker run -d -it -p $port:$port -p 1$port:1$port -v /usr/local/server/redis-
cluster/$port/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/server/redis-
cluster/$port/data:/data --privileged=true --restart always --name redis-$port --net
redis-net --sysctl net.core.somaxconn=1024 redis redis-server
/usr/local/etc/redis/redis.conf;
done
#查找ip
for port in `seq 7001 7006`;
do
echo -n "$(docker inspect --format ' (index .NetworkSettings.Networks "redis-
net").IPAddress ' "redis-$port")":$port" ";
done
#换行
echo -e "\\n"
#输入信息
read -p "请把输入要启动的docker容器名称,默认redis-7001:" DOCKER_NAME
#判断是否为空
if [ ! $DOCKER_NAME ];
then DOCKER_NAME='redis-7001';
fi
#进入容器
docker exec -it redis-7001 /bin/bash
这里涉及到了一个网络的定义 redis-net ,代码如下:
docker network create redis-net
移除脚本创建
创建 stop.sh 脚本,用于停止Redis容器,并且移除对应容器
#!/bin/bash
docker stop redis-7001 redis-7002 redis-7003 redis-7004 redis-7005 redis-7006
docker rm redis-7001 redis-7002 redis-7003 redis-7004 redis-7005 redis-7006
rm -rf 7001 7002 7003 7004 7005 7006
脚本授权:给 redis.sh 和 stop.sh 添加可执行权限:
chmod +x redis.sh
chmod +x stop.sh
执行脚本开始安装Redis节点,并进入到 /usr/local/bin 目录下执行 redis-cli 创建集群关联:
#执行集群几点创建
./redis.sh
#进入到任意一个安装好的redis节点的bin目录,里面有个脚本对象redis-cli,然后执行集群创建
./redis-cli --cluster create 172.18.0.2:7001 172.18.0.3:7002 172.18.0.4:7003 172.18.0.5:7004
172.18.0.6:7005 172.18.0.7:7006 --cluster-replicas 1
–cluster-replicas 表示有一个主有几个slave。
安装好了后,我们链接Redis效果如下:
3 主从复制
我们先来理解下主从同步,如下图:
1、Slave服务启动,主动连接Master,并发送SYNC命令,请求初始化同步;
2、Master收到SYNC后,执行BGSAVE命令生成RDB文件,并缓存该时间段内的写命令;
3、Master完成RDB文件后,将其发送给所有Slave服务器;
4、Slave服务器接收到RDB文件后,删除内存中旧的缓存数据,并装载RDB文件;
5、Master在发送完RDB后,即刻向所有Slave服务器发送缓存中的写命令;
我们可以用 DesktopManager 链接Redis集群,并测试数据,往redis集群添加2条数据,可以明显看到主从效果,效果如下:
上面是我们集群时随机创建的从节点,如果手动给指定节点添加从节点也是可以实现的,我们这里实现给 7001 添加一个从节点。
4 集群扩容收容
上面虽然创建了主从复制,但如果手动给节点添加一个从节点,有可能添加从节点,也有可能添加从节点,这是我们想要干的。接下来我们给集群节点添加指定的从节点。
我们安装 7007 、 7008 、 7009 几个Redis节点,然后将 7007 和 7008 作为主节点,添加到集群中, 7009 作为从节
点添加到集群中。
基于Docker安装Redis这里编写了一个脚本,安装脚本 redis-port.sh 如下:
#!/bin/bash
#在/usr/local/server/redis-cluster下生成conf和data目标,并生成配置信息
#换行
echo -e "\\n"
#输入信息
read -p "请输入容器端口:" DOCKER_PORT
#输入端口赋值
port=$DOCKER_PORT;
echo -e "$port"
#创建配置文件
mkdir -p ./$port/conf && PORT=$port envsubst < ./redis-cluster.tmpl >
./$port/conf/redis.conf && mkdir -p ./$port/data;
#创建redis容器
docker run -d -it -p $port:$port -p 1$port:1$port -v /usr/local/server/redis-
cluster/$port/conf/redis.conf:/usr/local/etc/redis/redis.conf -v /usr/local/server/redis-
cluster/$port/data:/data --privileged=true --restart always --name redis-$port --net
redis-net --sysctl net.core.somaxconn=1024 redis redis-server
/usr/local/etc/redis/redis.conf;
#查找ip
echo -n "启动$(docker inspect --format ' (index .NetworkSettings.Networks "redis-
net").IPAddress ' "redis-$port")":$port" 成功!";
echo -e "\\n"
我们执行 redis-port.sh 脚本,实现 7007,7008,7009 节点安装。
添加课执行权限:
chmod +x redis-port.sh
查看集群状态
主节点查看:
./redis-cli -p 7001 cluster nodes|grep master
主节点状态信息如下:
从节点查看:
./redis-cli -p 7001 cluster nodes|grep slave
从上面信息我们可以看出集群关系:
Master:7001 Slave:7005
Master:7002 Slave:7006
Master:7003 Slave:7004
4.1 添加集群主节点
我们需要给集群节点添加一个主节点,我们需要将 192.168.211.141:7007 节点添加到 192.168.211.141:7001 节
点所在的集群中,并且添加后作为主节点,添加命令行如下:
./redis-cli --cluster add-node 192.168.211.141:7007 192.168.211.141:7001
命令说明:
.将192.168.211.141:7007节点添加到192.168.211.141:7001节点所在的集群中
执行命令后,效果如下:
此时我们可以进入到集群节点之一查看此时的集群状态,我们进入到 7002 节点中输入 cluster node 查询,操作方法如下:
进入容器
docker exec -it redis-7002 /bin/bash
进入到redis-cli脚本目录
cd /usr/local/bin
登录7002节点
./redis-cli -p 7002 -c
查询集群状态
cluster nodes
效果如下:
4.2 哈希槽分配
从上面的集群节点信息我们可以看出一个问题,其他主节点都有一串数字范围,而刚才添加的 7007 节点没有这段数
字范围,这和Redis集群原理有关系,我们来讲解一下集群的原理,然后实现新增节点哈希槽(这段数字范围)的分配。
(Redis集群原理图)
Redis原理:
(1)Redis Cluster 特性之一是引入了槽的概念。一个redis集群包含 16384 个哈希槽。
(2)集群时,会将16384个哈希槽分别分配给每个Master节点,每个Master节点占16384个哈希槽中的一部分。
(3)执行GET/SET/DEL时,都会根据key进行操作,Redis通过CRC16算法对key进行计算得到该key所属Redis节点。
(4)根据key去指定Redis节点操作数据。
从原理上分析,因为之前 7001,7002,7003 已经瓜分了16384个哈希槽,所以再增加一个新节点是没有剩余哈希槽分
配的,所以新增的 7007 节点没有分配到哈希槽。我们只能重新分配哈希槽,才能让新增节点分配到一定的哈希槽,
重新分配哈希槽后,我们还要考虑之前其他Redis节点中的数据迁移。
重新分配Hash槽
我们将 7001,7002,7003 中的 100 个哈希槽挪给 7007 ,命令如下:
./redis-cli --cluster reshard 192.168.211.141:7001 --cluster-from
c9687b2ebec8b99ee14fcbb885b5c3439c58827f,80a69bb8af3737bce2913b2952b4456430a89eb3,612e4af8ea
e48426938ce65d12a7d7376b0b37e3 --cluster-to 443096af2ff8c1e89f1160faed4f6a02235822a7 --
cluster-slots 100
命令说明:
将节点
c9687b2ebec8b99ee14fcbb885b5c3439c58827f
80a69bb8af3737bce2913b2952b4456430a89eb3
612e4af8eae48426938ce65d12a7d7376b0b37e3
中的100个哈希槽移动到
443096af2ff8c1e89f1160faed4f6a02235822a7中
参数说明:
--cluster-from:表示slot目前所在的节点的node ID,多个ID用逗号分隔
--cluster-to:表示需要新分配节点的node ID
--cluster-slots:分配的slot数量
将100个哈希槽挪给7007后,我们查询下节点信息:
效果如下:
4.3 添加集群从节点
我们需要往集群中给 7007 节点添加一个从节点 7008 ,添加从节点的主要目的是提高高可用,防止主节点宕机后该
节点无法提供服务。添加从节点命令如下:
./redis-cli --cluster add-node 192.168.211.141:7008 192.168.211.141:7007 --cluster-slave -- cluster-master-id 443096af2ff8c1e89f1160faed4f6a02235822a7
命令说明:
将192.168.211.141:7008节点添加到192.168.211.141:7007对应的集群中,并且加入的节点为从节点,对应的主节点
id是443096af2ff8c1e89f1160faed4f6a02235822a7
参数说明:
add-node: 后面的分别跟着新加入的slave和slave对应的master
cluster-slave:表示加入的是slave节点
--cluster-master-id:表示slave对应的master的node ID
执行命令后,效果如下:
集群信息查看:
4.4 缩容
1)数据迁移
2)哈希槽迁移
3)从节点删除
4)主节点删除
在真实生产环境中,我们也会跟着我们的业务和环境执行缩容处理,比如双十一过后,流量没有那么大了,我们往往
会缩容处理,服务器开销。
Redis实现缩容,需要哈希槽重新分配,将需要移除的节点所分配的所有哈希槽值分配给其他需要运行工作的节点,
还需要移除该节点的从节点,然后再删除该节点。
移除从节点
移除 7007 的从节点 7008 ,命令如下:
./redis-cli --cluster del-node 192.168.211.141:7008 98be71d8d6eff6bd40947fa0441e5a821dce20ae
参数说明:
del-node:删除节点,后面跟着slave节点的 ip:port 和node ID
删除后,我们再来查看集群节点,此时再无7008节点。
迁移Master的Slot
我们需要将 7007 节点的哈希槽迁移到 7001,7002,7003 节点上,仍然用上面用过的 redis-cli --cluster reshard
语法,命令如下:
第1次迁移:
./redis-cli --cluster reshard 192.168.211.141:7007 --cluster-from
443096af2ff8c1e89f1160faed4f6a02235822a7 --cluster-to
80a69bb8af3737bce2913b2952b4456430a89eb3 --cluster-slots 33 --cluster-yes
命令说明:
将192.168.211.141:7007节点所在集群中443096af2ff8c1e89f1160faed4f6a02235822a7节点的33个哈希槽迁移给
80a69bb8af3737bce2913b2952b4456430a89eb3节点,不回显需要迁移的slot,直接迁移。
效果如下:
查看集群节点:
我们再次迁移其他哈希槽到其他节点,将剩余的哈希槽迁移到7002和7003去。
第2次迁移:
./redis-cli --cluster reshard 192.168.211.141:7007 --cluster-from
443096af2ff8c1e89f1160faed4f6a02235822a7 --cluster-to
c9687b2ebec8b99ee14fcbb885b5c3439c58827f --cluster-slots 34 --cluster-yes
第3次迁移:
./redis-cli --cluster reshard 192.168.211.141:7007 --cluster-from
443096af2ff8c1e89f1160faed4f6a02235822a7 --cluster-to
612e4af8eae48426938ce65d12a7d7376b0b37e3 --cluster-slots 33 --cluster-yes
集群状态查询:
删除7007主节点
删除节点命令如下:
./redis-cli --cluster del-node 192.168.211.141:7007 443096af2ff8c1e89f1160faed4f6a02235822a7
效果如下:
集群节点查看:
5 Redis Sentinel
哨兵是用来解决redis高可用性的,可以监控集群中主从的变化,然后进行故障转移。
5.1 哨兵讲解
一套合理的监控机制是Sentinel节点判定节点不可达的重要保证,Redis Sentinel通过三个定时监控任务完成对各个
节点发现和监控。
周期10秒监控
每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的主从结构,该命令有3个作用:
1、通过向主节点执行info命令,获取从节点的信息,这也是为什么 Sentinel节点不需要显式配置监控从节点
2、当有新的从节点加入时都可以立刻感知出来
3、节点不可达或者故障转移后,可以通过info命令实时更新节点结构信息
周期2秒监控
每隔2秒,每个Sentinel节点会向Redis数据节点的 sentinel:hello 频道上发送该Sentinel节点对于主节点的
判断以及当前Sentinel节点的信息 ,同时每个Sentinel节点也会订阅该频道,来了解其他 Sentinel节点以及它们对主
节点的判断。
该定时任务主要有2个作用:
1、发现新的Sentinel节点:通过订阅主节点的__sentinel__:hello了解其他的Sentinel节点信息,如果是新加入的
Sentinel节点,将该Sentinel节点信息保存起来,并与该Sentinel节点创建连接。
2、Sentinel节点之间交换主节点的状态,作为后面客观下线以及领导者选举的依据。
周期1秒监控
每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些
节点当前是否可达,从而实现检查每个节点的健康状态。
Redis-Sentinel是用于管理Redis集群,主要执行如下任务:
1、监控(Monitoring)
Sentinel会不断地检查你的主服务器和从服务器是否运作正常;
2、提醒(Notification)
当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知;
3、自动故障迁移(Automatic failover)
当一个主服务器不能正常工作时,Sentinel 会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升
级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向
客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器.
执行流程
哨兵来实现Redis高可用有这5个流程:
1、判断主节点是否是主观下线sdown。(主观是指当前节点判断的结果,sdown表示该节点判断该Redis宕机了)
2、一旦主节点的主观下线到了一定数量,哨兵群进行客观下线odown的判断。(客观指也有其他Sentinel节点也判断该
Redis宕机了,并且数量达到了设置的值)
3、哨兵群选举一个Leader,准备对客观下线的节点进行故障转移。
4、Leader选择一个slave a,其他哨兵确认。
5、其他slave成为a的slave。
状态说明
节点状态分为:ok、主观下线、客观下线。
正常(ok):就是节点在线,能够正常响应哨兵的检测和命令。
主观下线(sdown):指单个哨兵,发现主节点在down-after-milliseconds时间内无正确响应,做出的状态判断。
客观下线(odown):指多个哨兵对一个主节点做了sdown判断后,互相使用is-master-down-by-addr命令交流后,做
出的节点已经下线的判断。
5.2 Sentinel搭建
我们这里搭建3个哨兵,采用Docker的方式搭建。
拷贝 /usr/local/server/redis-cluster 下的单节点 redis 到 /usr/local/server/redis-cluster/sentinel/
目录下,分别拷贝3分,命名为 sentinel , sentinel2 , sentinel3 ,并且修改每个目录下的配置文件
sentinel.conf ,修改 port 、监听节点信息、后台运行,配置如下:
第1台的 sentinel.conf :
port 8001
sentinel monitor mymaster 192.168.211.141 7001 2
daemonize yes
第2台的 sentinel.conf :
port 8002
sentinel monitor mymaster 192.168.211.141 7002 2
daemonize yes
第3台的 sentinel.conf :
port 8003
sentinel monitor mymaster 192.168.211.141 7003 2
daemonize yes
参数说明:
sentinel monitor mymaster 192.168.211.141 7003 2
表示执行Sentinel监控,mymaster给当前监控取个名字,可以随意取,192.168.211.141 7003,表示监听该主节点,2
表示有2个sentinel主观(sdown)认为该节点宕机了,则该节点就编程下线状态(odown)
启动:(到每台sentinel的bin目录下执行启动)
./redis-sentinel ./sentinel.conf
5.3 Sentinel集群讲解
启动Sentinel后,会有很多日志信息:
我们可以测试下故障自动转移,停掉 redis-7001 节点,可以看到如下日志:
此时哨兵这边会出现如下日志,表示7001节点客观上宕机次数-1,并且将该节点添加为7005的从节点:
日志信息表:
+reset-master <instance details> :主服务器已被重置。
+slave <instance details> :一个新的从服务器已经被 Sentinel 识别并关联。
+failover-state-reconf-slaves <instance details> :故障转移状态切换到了 reconf-slaves 状态。
+failover-detected <instance details> :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成
了主服务器。
+slave-reconf-sent <instance details> :领头(leader)的 Sentinel 向实例发送了 SLAVEOF 命令,为实例
设置新的主服务器。
+slave-reconf-inprog <instance details> :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程
仍未完成。
+slave-reconf-done <instance details> :从服务器已经成功完成对新主服务器的同步。
-dup-sentinel <instance details> :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除
—— 当 Sentinel 实例重启的时候,就会出现这种情况。
+sentinel <instance details> :一个监视给定主服务器的新 Sentinel 已经被识别并添加。
+sdown <instance details> :给定的实例现在处于主观下线状态。
-sdown <instance details> :给定的实例已经不再处于主观下线状态。
+odown <instance details> :给定的实例现在处于客观下线状态。
-odown <instance details> :给定的实例已经不再处于客观下线状态。
+new-epoch <instance details> :当前的纪元(epoch)已经被更新。
+try-failover <instance details> :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中
(waiting to be elected by the majority)。
+elected-leader <instance details> :赢得指定纪元的选举,可以进行故障迁移操作了。
+failover-state-select-slave <instance details> :故障转移操作现在处于 select-slave 状态 ——
Sentinel 正在寻找可以升级为主服务器的从服务器。
no-good-slave <instance details> :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间
之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。
selected-slave <instance details> :Sentinel 顺利找到适合进行升级的从服务器。
failover-state-send-slaveof-noone <instance details> :Sentinel 正在将指定的从服务器升级为主服务
器,等待升级功能完成。
failover-end-for-timeout <instance details> :故障转移因为超时而中止,不过最终所有从服务器都会开始复制
新的主服务器(slaves will eventually be configured to replicate with the new master anyway)。
failover-end <instance details> :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。
+switch-master <master name> <oldip> <oldport> <newip> <newport> :配置变更,主服务器的 IP 和地址
已经改变。 这是绝大多数外部用户都关心的信息。
+tilt :进入 tilt 模式。
-tilt :退出 tilt 模式。
项目中链接Redis集群或者Redis哨兵,只需要配置一下 application.yml即可 :
spring:
#Redis
redis:
#timeout: 50000
sentinel:
nodes: 192.168.211.141:8001,192.168.211.141:8002,192.168.211.141:8003
#cluster:
# nodes:
192.168.211.141:7001,192.168.211.141:7002,192.168.211.141:7003,192.168.211.141:7004,192.168.
211.141:7005,192.168.211.141:7006
6 # 5 redis集群模式部署
现状问题:
业务发展过程中遇到的峰值瓶颈
- redis提供的服务OPS可以达到10万/秒,当前业务OPS已经达到10万/秒
- 内存单机容量达到256G,当前业务需求内存容量1T
- 使用集群的方式可以快速解决上述问题
6 集群部署3主3从
集群就是使用网络将若干台计算机联通起来,并提供统一的管理方式,使其对外呈现单机的服务效果
集群作用:
1. 分散单台服务器的访问压力,实现负载均衡
2. 分散单台服务器的存储压力,实现可扩展性
3. 降低单台服务器宕机带来的业务灾难
6.1 Cluster集群结构设计
数据存储设计
haha,hash值(crc16(key))% 16384,
- 通过算法设计,计算出key应该保存的位置
- 将所有的存储空间计划切割成16384份,每台主机保存一部分
- 注意:每份代表的是一个存储空间,不是一个key的保存空间
- 将key按照计算出的结果放到对应的存储空间
- 增强其可扩展性
slot
集群内部通讯设计
- 各个数据库相互通信,保存各个库中槽的编号数据
- 一次命中,直接返回
- 一次未命中,告知具体位置
6.2 Cluster集群结构搭建
搭建方式
1. 配置服务器(3主3从)
2. 建立通信(Meet)
3. 分槽(Slot)
4. 搭建主从(master-slave)
Cluster配置:
- 是否启用cluster,加入cluster节点
cluster-enabled yes|no
- cluster配置文件名,该文件属于自动生成,仅用于快速查找文件并查询文件内容
cluster-config-file filename
- 节点服务响应超时时间,用于判定该节点是否下线或切换为从节点
cluster-node-timeout milliseconds
- master连接的slave最小数量
cluster-migration-barrier min_slave_number
Cluster节点操作命令:
-
查看集群节点信息
cluster nodes
2. 更改slave指向新的master
```bash
cluster replicate master-id
- 发现一个新节点,新增master
cluster meet ip:port
- 忽略一个没有solt的节点
cluster forget server_id
- 手动故障转移
cluster failover
redis-cli命令
- 创建集群
redis-cli
–-cluster create masterhost1:masterport1 masterhost2:masterport2
masterhost3:masterport3 [masterhostn:masterportn …] slavehost1:slaveport1
slavehost2:slaveport2 slavehost3:slaveport3 ––cluster-replicas n
master与slave的数量要匹配,一个master对应n个slave,由最后的参数n决定
master与slave的匹配顺序为第一个master与前n个slave分为一组,形成主从结构
- 添加master到当前集群中,连接时可以指定任意现有节点地址与端口
redis-cli
--cluster add-node new-master-host:new-master-port now-host:now-port
- 添加slave
redis-cli
--cluster add-node new-slave-host:new-slave-port master-host:master-port
--cluster-slave --cluster-master-id masterid
- 删除节点,如果删除的节点是master,必须保障其中没有槽slot
redis-cli --cluster del-node del-slave-host:del-slave-port del-slave-id
- 重新分槽,分槽是从具有槽的master中划分一部分给其他master,过程中不创建新的槽
redis-cli
--cluster reshard new-master-host:new-master:port
--cluster-from srcmaster-id1, src-master-id2, src-master-idn
--cluster-to target-master-id --cluster-slots slots
将需要参与分槽的所有masterid不分先后顺序添加到参数中,使用,分隔
指定目标得到的槽的数量,所有的槽将平均从每个来源的master处获取
- 重新分配槽,从具有槽的master中分配指定数量的槽到另一个master中,常用于清空指定master中的槽
redis-cli
--cluster reshard src-master-host:src-master-port
--cluster-from srcmaster-id --cluster-to target-master-id
--cluster-slots slots --cluster-yes
6.3 docker实战部署
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建6个redis配置
for port in $(seq 1 6); \\
do \\
mkdir -p /mydata/redis/node-$port/conf
touch /mydata/redis/node-$port/redis.conf
cat << EOF >/mydata/redis/node-$port/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1$port
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
docker run -p 637$port:6379 -p 1637$port:16379 --name redis-$port -v /mydata/redis/node-$port/data:/data -v /mydata/redis/node-$port/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.1$port redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 启动redis
docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /mydata/redis/node-1/data:/data -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6372:6379 -p 16372:16379 --name redis-2 -v /mydata/redis/node-2/data:/data -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6373:6379 -p 16373:16379 --name redis-3 -v /mydata/redis/node-3/data:/data -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6374:6379 -p 16374:16379 --name redis-4 -v /mydata/redis/node-4/data:/data -v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6375:6379 -p 16375:16379 --name redis-5 -v /mydata/redis/node-5/data:/data -v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
docker run -p 6376:6379 -p 16376:16379 --name redis-6 -v /mydata/redis/node-6/data:/data -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 创建集群
[root@iZwz9gcg5lpw0sp5r86b4dZ ~]# docker exec -it 038e7082bc80 /bin/sh
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 10ace5a4f2a36504adccef1c4470b9e286ef8da1 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 7b1aa1d177aabe07f1a44e2139b584398ec965fb 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: d48eed0b198ac9acd9aab054d22f4b1127130276 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: dca1b6f5ba61f1f2455f936a66ac6c276b602799 172.38.0.14:6379
replicates d48eed0b198ac9acd9aab054d22f4b1127130276
S: e649283604139748551c55344a95d3fdc27b69f1 172.38.0.15:6379
replicates 10ace5a4f2a36504adccef1c4470b9e286ef8da1
S: d785767af99564c5d481db41483740078b53d423 172.38.0.16:6379
replicates 7b1aa1d177aabe07f1a44e2139b584398ec965fb
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
Docker 部署 Redis 高可用集群 (sentinel 哨兵模式)