一、Redis高可用的概念
在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。
但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(如主从分离、快速容灾技术),还需要考虑数据容量的扩展、数据安全不会丢失等。
二、Redis高可用的技术
在Redis中,实现高可用的技术主要包括持久化、主从复制、哨兵和cluster集群,下面分别说明它们的作用,以及解决了什么样的问题。
-
持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
-
主从复制:主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份(和同步),以及对于读操作的负载均衡和简单的故障恢复。
- 缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
-
哨兵模式:在主从复制的基础上,哨兵模式实现了自动化的故障恢复。(主挂了,找一个从成为新的主,哨兵节点进行监控)
- 缺陷:写操作无法负载均衡;存储能力受到单机的限制。
-
Cluster集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。(6台起步,成双成对,3主3从)
Redis持久化
持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。
三、Redis主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(Slave);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从模式(master/slave),可以实现Redis数据的跨主机备份。
主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
主从复制的特点:
- 一个master可以有多个slave
- 一个slave只能有一个master
- 数据流向是从master到slave单向的
四、Redis主从复制的作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
五、Redis主从复制的流程
- 若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接。
- 无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。
- 后台进程完成缓存操作之后,Master机器就会向Slave机器发送数据文件,Slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。
- Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Master同时收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常。
Redis主从复制分为全量同步和增量同步。
具体主从同步过程如下:
1)从服务器连接主服务器,发送PSYN(同步)C命令
2)主服务器接收到PSYNC命令后,开始执行BGSAVE命令生成RDB快照文件并使用缓冲区记录此后执行的所有写命令
3)主服务器BGSAVE执行完后,向所有从服务器发送RDB快照文件,并在发送期间继续记录被执行的写命令
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照至内存
5)主服务器快照发送完毕后,开始向从服务器发送缓冲区中的写命令
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令
7)后期同步会先发送自己slave_repl_offset位置,只同步新增加的数据,不再全量同步
六、Redis主从复制的部署
当配置Redis复制功能时,强烈建议打开主服务器的持久化功能。否则的话,由于延迟等问题,部署的主节点Redis服务应该要避免自动启动。
Redis Slave 也要开启持久化并设置和master同样的连接密码,因为后期slave会有提升为master的可能,Slave 端切换master同步后会丢失之前的所有数据,而通过持久化可以恢复数据。
一旦某个Slave成为一个master的slave,Redis Slave服务会清空当前redis服务器上的所有数据并将master的数据导入到自己的内存,但是如果只是断开同步关系后,则不会删除当前已经同步过的数据。
1. Redis主从复制
- master:192.168.100.20
- slave1:192.168.100.30
- slave2:192.168.100.40
Redis主服务器master
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf //修改配置文件
70 bind 0.0.0.0 //将监听端口改为任意端口
172 logfile /apps/redis/log/redis6379.log //指定日志文件目录
264 dir /apps/redis/data/ //指定工作目录
700 appendonly yes //开启AOF持久化功能
[root@localhost data]# systemctl restart redis //重启服务
Redis从服务器slave1
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf
70 bind 0.0.0.0
172 logfile /apps/redis/log/redis6379.log
264 dir /apps/redis/data/
288 replicaof 192.168.100.20 6379 //设置 主从配置
700 appendonly yes
[root@localhost data]# systemctl restart redis
Redis从服务器slave2
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf
70 bind 0.0.0.0
172 logfile /apps/redis/log/redis6379.log
264 dir /apps/redis/data/
288 replicaof 192.168.100.20 6379 //设置 主从配置
700 appendonly yes
[root@localhost data]# systemctl restart redis
2. Redis的级联复制
master和slave1节点无需修改,只需要修改slave2指向slave1做为mater即可。
- master:192.168.100.20
- slave1/master1:192.168.100.30
- slave2:192.168.100.40
Redis主服务器master
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf //修改配置文件
70 bind 0.0.0.0 //将监听端口改为任意端口
172 logfile /apps/redis/log/redis6379.log //指定日志文件目录
264 dir /apps/redis/data/ //指定工作目录
700 appendonly yes //开启AOF持久化功能
[root@localhost data]# systemctl restart redis //重启服务
Redis从服务器slave1
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf
70 bind 0.0.0.0
172 logfile /apps/redis/log/redis6379.log
264 dir /apps/redis/data/
288 replicaof 192.168.100.20 6379 //设置 主从配置
700 appendonly yes
[root@localhost data]# systemctl restart redis
Redis从服务器slave2
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf
70 bind 0.0.0.0
172 logfile /apps/redis/log/redis6379.log
264 dir /apps/redis/data/
288 replicaof 192.168.100.30 6379 //设置 主从配置
700 appendonly yes
[root@localhost data]# systemctl restart redis
七、主从复制优化
1. 复制缓冲区(环形队列)配置参数
//复制缓冲区大小,建议要设置足够大
repl-backlog-size 1mb
//Redis同时也提供了当没有slave需要同步的时候,多久可以释放环形队列:
repl-backlog-ttl 3600 //最长保持时间 3600秒
2. 避免全量复制
- 第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),业务低峰时进行全量
- 节点运行ID不匹配:主节点重启会导致RUNID变化,可能会触发全量复制,可以利用故障转移,例如哨兵或集群,而从节点重启动,不会导致全量复制
- 复制积压缓冲区不足: 当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点连接后,会导致全量复制。解决方法将 repl-backlog-size 调大。
3. 避免复制风暴
-
单主节点复制风暴
- 当主节点重启,多从节点复制。解决方法:更换复制拓扑
-
单机器多实例复制风暴
- 机器宕机后,大量全量复制。解决方法:主节点分散多机器
4. 性能相关配置
repl-diskless-sync no
//是否使用无盘同步RDB文件,默认为no,no为不使用无盘,需要将RDB文件保存到磁盘后再发送给slave,yes为支持无盘,支持无盘就是RDB文件不需要保存至本地磁盘,而且直接通过socket文件发送给slave
repl-diskless-sync-delay 5
//diskless时复制的服务器等待的延迟时间
repl-ping-slave-period 10
//slave端向server端发送ping的时间间隔,默认为10秒
repl-timeout 60
//设置主从ping连接超时时间,超过此值无法连接,master_link_status显示为down,并记录错误日志
repl-disable-tcp-nodelay no
//是否启用TCP_NODELAY,如设置成yes,则redis会合并小的TCP包从而节省带宽, 但会增加同步延迟(40ms),造成master与slave数据不一致,假如设置成no,则redis master会立即发送同步数据,没有延迟,yes关注网络性能,no关注redis服务中的数据一致性
repl-backlog-size 1mb
//master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:repl-backlog-size = 允许从节点最大中断时长 * 主实例offset每秒写入量,比如master每秒最大写入64mb,最大允许60秒,那么就要设置为64mb*60秒=3840MB(3.8G),建议此值是设置的足够大
repl-backlog-ttl 3600
//3600秒 如果一段时间后没有slave连接到master,则backlog size的内存将会被释放。如果值为0则 表示永远不释放这部份内存。
slave-priority 100
//slave端的优先级设置,值是一个整数,数字越小表示优先级越高。当master故障时将会按照优先级来选择slave端进行恢复,如果值设置为0,则表示该slave永远不会被选择。
min-replicas-to-write 1
//设置一个master的可用slave不能少于多少个,否则master无法执行写
min-slaves-max-lag 20
//设置至少有上面数量的slave延迟时间都大于多少秒时,master不接收写操作(拒绝写入)
5. 常见主从复制故障
- master密码不对
即配置的master密码不对,导致验证不通过而无法建立主从同步关系。
- Redis版本不一致
不同的redis 大版本之间存在兼容性问题,比如:3和4,4和5之间,因此各master和slave之间必须保持版本一致。
- 无法远程连接
在开启了安全模式情况下,没有设置bind地址或者密码。
- 配置不一致
主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据rename-command 命令不一致,如在主节点定义了fushall,flushdb,从节点没定义,结果执行flushdb,不同步。
八、 Redis哨兵模式 (Sentinel)
哨兵模式(sentinel):是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的Master,并将所有Slave 连接到新的Master。所以整个运行哨兵的集群的数量不得少于3个节点。
哨兵的核心功能:在主从复制的基础上,哨兵引入了主节点的自动故障转移。
Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持。默认监听在 26379/𝑡𝑐𝑝 端口。
1. Redis哨兵的工作原理
sentinel中的三个定时任务:
-
每10秒每个sentinel对master和slave执行info
- 发现slave节点
- 确认主从关系
-
每2秒每个sentinel通过master节点的channel交换信息(pub/sub)
- 通过sentinel__:hello频道交互
- 交互对节点的“看法”和自身信息
-
每1秒每个sentinel对其他sentinel和redis执行ping
2.哨兵模式的作用
监控:哨兵会不断地检查主节点和从节点是否运作正常。 自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。 通知(提醒):哨兵可以将故障转移的结果发送给客户端。
3.哨兵模式的部署
- master:192.168.100.20
- slave1:192.168.100.30
- slave2:192.168.100.40
首先完成Redis主从复制部署
Redis主服务器master
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf //修改配置文件
70 bind 0.0.0.0 //将监听端口改为任意端口
masterauth "123456"
requirepass "123456"
172 logfile /apps/redis/log/redis6379.log //指定日志文件目录
264 dir /apps/redis/data/ //指定工作目录
700 appendonly yes //开启AOF持久化功能
[root@localhost data]# systemctl restart redis //重启服务
Redis从服务器slave1
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf
70 bind 0.0.0.0
172 logfile /apps/redis/log/redis6379.log
264 dir /apps/redis/data/
288 replicaof 192.168.100.20 6379 //设置 主从配置
700 appendonly yes
[root@localhost data]# systemctl restart redis
Redis从服务器slave2
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0
[root@localhost ~]# mkdir /data
[root@localhost ~]# cd /data
[root@localhost data]# rz -E //安装Redis安装包
rz waiting to receive.
[root@localhost data]# ls
redis_install.sh
[root@localhost data]# bash redis_install.sh //执行安装Redis脚本
[root@localhost data]# vim /apps/redis/etc/redis.conf
70 bind 0.0.0.0
172 logfile /apps/redis/log/redis6379.log
264 dir /apps/redis/data/
288 replicaof 192.168.100.20 6379 //设置 主从配置
700 appendonly yes
[root@localhost data]# systemctl restart redis
然后在master服务器上编辑哨兵模式的配置文件
[root@localhost data]# ls
redis-5.0.7 redis-5.0.7.tar.gz redis_install.sh
[root@localhost data]# cd redis-5.0.7/
[root@localhost redis-5.0.7]# ls
00-RELEASENOTES CONTRIBUTING deps Makefile README.md runtest runtest-moduleapi sentinel.conf tests
BUGS COPYING INSTALL MANIFESTO redis.conf runtest-cluster runtest-sentinel src utils
[root@localhost redis-5.0.7]# cp sentinel.conf /apps/redis/etc/
[root@localhost redis-5.0.7]# cd /apps/redis/etc/
[root@localhost etc]# ls
redis.conf sentinel.conf
[root@localhost etc]# chown -R redis.redis /apps/redis/etc/
[root@localhost etc]# vim sentinel.conf //编辑配置文件
16 bind 0.0.0.0 //修改监听端口
22 port 26379 //默认监听端口,不用修改
27 daemonize no //不用修改
32 pidfile /apps/redis/run/redis-sentinel.pid //指定pid文件位置
37 logfile /apps/redis/log/sentinel.log //指定日志文件位置
66 dir /tmp //工作目录不用修改
85 sentinel monitor mymaster 192.168.100.20 6379 2
//mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口。2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移
88 sentinel auth-pass mymaster 123456
//mymaster集群中master的密码
115 sentinel down-after-milliseconds mymaster 3000
//(SDOWN)判断mymaster集群中所有节点的主观下线的时间。单位:毫秒
123 sentinel parallel-syncs mymaster 1
//发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力
148 sentinel failover-timeout mymaster 1800
//所有slaves指向新的master所需的超时时间,单位:毫秒
//拷贝主服务器的配置文件到从服务器上
[root@localhost etc]# scp sentinel.conf 192.168.204.50:/apps/redis/etc/ //拷贝配置文件
[root@localhost etc]# scp sentinel.conf 192.168.204.70:/apps/redis/etc/
//在slave1服务器上修改权限
[root@localhost ~]# cd /apps/redis/etc/
[root@localhost etc]# chown redis.redis sentinel.conf
//在slave2服务器上修改权限
[root@localhost ~]# cd /apps/redis/etc/
[root@localhost etc]# chown redis.redis sentinel.conf
在各个服务器上准备service文件,全部节点都需要,注意先开主,再开从*
[root@localhost etc]# cat >> /lib/systemd/system/redis-sentinel.service <<eof
> [Unit]
> Description=Redis Sentinel
> After=network.target
> [Service]
> ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd
> ExecStop=/bin/kill -s QUIT $MAINPID
> User=redis
> Group=redis
> RuntimeDirectory=redis
> RuntimeDirectoryMode=0755
> [Install]
> WantedBy=multi-user.target
> eof
[root@localhost etc]# systemctl daemon-reload
[root@localhost etc]# systemctl start redis-sentinel.service
[root@localhost etc]# ss -natp |grep 26379
关掉主服务器验证
[root@localhost etc]# systemctl stop redis
九、Redis Cluster 集群模式
1. Redis Cluster 工作原理
在哨兵sentinel机制中,可以解决redis高可用问题,即当master故障后可以自动将slave提升为master,从而可以保证redis服务的正常使用,但是无法解决redis单机写入的瓶颈问题,即单机redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素。
为了解决单机性能的瓶颈,提高Redis 性能,可以使用分布式集群的解决方案。
Redis Cluster 特点如下:
- 所有Redis节点使用(PING机制)互联
- 集群中某个节点的是否失效,是由整个集群中超过半数的节点监测都失效,才能算真正的失效
- 客户端不需要proxy即可直接连接redis,应用程序中需要配置有全部的redis服务器IP
- redis cluster把所有的redis node 平均映射到 0-16383 槽位 上,读写需要到指定的redis node上进行操作,因此有多少个redis node相当于redis 并发扩展了多少倍,每个redis node 承担16384/N个槽位
- Redis cluster预先分配16384个(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使用CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。
2. Redis Cluster集群模式的作用
-
数据分区:数据分区(或称数据分片)是集群最核心的功能。
- 集群将数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加;另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力。
- Redis单机内存大小受限问题,在介绍持久化和主从复制时都有提及;例如,如果单机内存太大,bgsave和bgrewriteaof的fork操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出。
-
高可用:集群支持主从复制和主节点的自动故障转移(与哨兵类似);当任一节点发生故障时,集群仍然可以对外提供服务。
通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。
3. Redis Cluster 集群模式的部署
redis的集群一般需要6个节点,3主3从。方便起见,开启多实例,所有节点在同一台服务器上模拟。 以端口号进行区分:3个主节点端口号:6001/6002/6003,对应的从节点端口号:6004/6005/6006 (可能随机搭配)
- 新建集群文件目录
[root@localhost data]# cd /apps/redis/
[root@localhost redis]# mkdir -p redis-cluster/redis600{1..6}
- 准备可执行文件到每个文件夹
[root@localhost redis]# for i in {1..6}
> do
> cp /data/redis-5.0.7/redis.conf /apps/redis/redis-cluster/redis600$i
> cp /data/redis-5.0.7/src/redis-cli /data/redis-5.0.7/src/redis-server /apps/redis/redis-cluster/redis600$i
> done
- 开启群集功能
[root@localhost redis]# cd /apps/redis/redis-cluster/redis6001/
[root@localhost redis6001]# vim redis.conf
70 bind 0.0.0.0 //监听所有网卡
89 protected-mode no //关闭保护模式
93 port 6001 //修改redis监听端口
137 daemonize yes //开启守护进程
701 appendonly yes //开启AOF持久化
834 cluster-enabled yes //开启群集功能
842 cluster-config-file nodes-6001.conf //群集名称文件设置
848 cluster-node-timeout 15000 //群集超时时间设置
[root@localhost redis6001]# for i in {2..6} //复制配置文件,注意要切换到redis6001目录下执行
> do
> \cp -f ./redis.conf /apps/redis/redis-cluster/redis600${i}
> done
//其他5个文件夹的配置文件以此类推修改,注意6个端口都要不一样
[root@localhost redis6001]# sed -i 's/6001/6002/' /apps/redis/redis-cluster/redis6002/redis.conf
[root@localhost redis6001]# sed -i 's/6001/6003/' /apps/redis/redis-cluster/redis6003/redis.conf
[root@localhost redis6001]# sed -i 's/6001/6004/' /apps/redis/redis-cluster/redis6004/redis.conf
[root@localhost redis6001]# sed -i 's/6001/6005/' /apps/redis/redis-cluster/redis6005/redis.conf
[root@localhost redis6001]# sed -i 's/6001/6006/' /apps/redis/redis-cluster/redis6006/redis.conf
[root@localhost redis-cluster]# chown -R redis.redis /apps/redis/
- 启动Redis节点
[root@localhost redis-cluster]# cd /apps/redis/redis-cluster/redis6001 //切换目录
[root@localhost redis6001]# for d in {1..6} //用脚本启动
> do
> cd /apps/redis/redis-cluster/redis600$d
> redis-server redis.conf
> done
- 查看是否启动成功
[root@localhost redis6006]# ss -natp |grep "\b600[1-6]\b"
LISTEN 0 128 *:6001 *:* users:(("redis-server",pid=46771,fd=6))
LISTEN 0 128 *:6002 *:* users:(("redis-server",pid=46776,fd=6))
LISTEN 0 128 *:6003 *:* users:(("redis-server",pid=46778,fd=6))
LISTEN 0 128 *:6004 *:* users:(("redis-server",pid=46786,fd=6))
LISTEN 0 128 *:6005 *:* users:(("redis-server",pid=46791,fd=6))
LISTEN 0 128 *:6006 *:* users:(("redis-server",pid=46795,fd=6))
- 启动集群
[root@localhost redis6006]# redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1
//六个实例分为三组,每组一主一从,前面的做主节点,后面的做从节点。下面交互的时候 需要输入yes才可以创建。
//--replicas 1 表示每个主节点有1个从节点
- 测试集群
[root@localhost redis6006]# redis-cli -p 6001 -c //加-c参数,节点之间就可以互相跳转
127.0.0.1:6001> cluster slots //查看节点的哈希槽编号范围
1) 1) (integer) 10923 //哈希槽编号范围
2) (integer) 16383
3) 1) "127.0.0.1"
2) (integer) 6003 //主节点IP和端口号
3) "3d17bef8addb0b4426b67498a445dbf067865ca4"
4) 1) "127.0.0.1"
2) (integer) 6006 //从节点IP和端口号
3) "53025048919b8bbc49fb691059a638e02e59793f"
2) 1) (integer) 0
2) (integer) 5460
3) 1) "127.0.0.1"
2) (integer) 6001
3) "70f8916c9de514bce3035f8056fc231d7f29db49"
4) 1) "127.0.0.1"
2) (integer) 6004
3) "e2c5aa3ff0827a882c21cd5f8d13689147d054b9"
3) 1) (integer) 5461
2) (integer) 10922
3) 1) "127.0.0.1"
2) (integer) 6002
3) "f0d0579f35025de3d392ef6d5b7a5190ee5e518d"
4) 1) "127.0.0.1"
2) (integer) 6005
3) "91e9fe6edcccfae0cf3cf6566eeabfbbd9a35f43"
- 生成数据测试
127.0.0.1:6001> keys *
(empty list or set)
127.0.0.1:6001> set name LHEY //对name键进行算法,得出值为5789,跳到对应的节点存储
-> Redirected to slot [5798] located at 127.0.0.1:6002
OK
127.0.0.1:6002> keys * //此处可以看到跳转到6002
1) "name"
- 查看节点信息
127.0.0.1:6002> cluster nodes //查看节点信息
十、总结
三种模式需要注意修改不同的配置文件
主从复制:vim /etc/redis/6379.conf
哨兵模式:vim /opt/redis-5.0.7/sentinel.conf
cluster集群:vim /opt/redis-5.0.7/redis.conf
-
持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
-
主从复制:主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份(和同步),以及对于读操作的负载均衡和简单的故障恢复。
- 缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
-
哨兵模式:在主从复制的基础上,哨兵模式实现了自动化的故障恢复。(主挂了,找一个从成为新的主,哨兵节点进行监控)
- 缺陷:写操作无法负载均衡;存储能力受到单机的限制。
-
Cluster集群:通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。(6台起步,成双成对,3主3从)
redis哨兵模式的结构
- 数据节点:主从复制架构中的主节点和从节点,存储数据的
- 哨兵节点:不存储数据,由一个或多个(奇数个)哨兵节点组成。监控主从和其它哨兵节点,主节点自动故障转移,通知故障转移结果
redis哨兵模式的工作流程
- 每个哨兵节点会定期的给主从节点和其它哨兵节点发送心跳消息(ping),如果主节点在超时时间内没有回复或回复错误消息,那么哨兵节点会认为该主节点为主观下线,当到达一定数量的哨兵节点认为该主节点主观下线了,则改主节点则为客观下线
- 哨兵节点会通过算法选举出一个leader来负责主节点的故障转移和通知
- leader会根据从节点的优先级设置或者偏移量挑选出-一个从节点为新的主节点,并让其它从节点指向新的主节点做主从复制
- 若原来的主节点恢复了会变成从节点指向新的主节点
端口号
- 6379:redis端口号,客户端服务端数据通信,或者主从节点间数据通信
- 16379:用于集群总线,这是一个用二 进制协议的点对点通信信道。这个集群总线(Cluster bus)用于节点的失败侦测、配置更新、故障转移授权,等等。
- 26379:哨兵节点间通信