Redis集群
为了达到redis的高可用,避免redis的单点故障,来部署多个redis机器。
但是一旦部署多台机器,不同机器上数据的同步问题就变成不可避免的了。
为了解决这个问题,redis提供了复制功能,也就是我们常说的主从复制。
Redis主从复制
主从复制指的是当有多台redis服务部署时,这些redis服务节点往往会分成两中,一种叫主节点master,另一种叫从节点slave。master主节点能读也能写,但是slave从节点只能读不能写,当主节点进行了数据的增删改操作,会将更改之后的数据同步给相应的从节点。但主节点往往只负责写,把读的工作交给从节点,达到一个读写分离的效果。一个从节点只能对应一个主节点,但一个主节点能对应多个从节点,这就是一主多从结构,从节点还可以对应多个从节点,这就构成了级联结构。
使用多台机器来学习使用redis集群有些困难,所以我们这里退而求其次,选择使用一台机器创建多台redis实例来完成。
创建多台redis实例
- 复制多个redis.conf文件,更改为不同的名字
- 配置这些文件
修改配置文件中的这些项
#指定redis以守护进程的方式启动(一般时默认)
Daemonize yes
#配置端口
port 6379
#配置pid文件
pidfile /文件路径/redis-6379.pid
#配置log文件
logfile /文件路径/redis-6379.log
- 分别启动客户端
或者
先将redis-server 复制到各个实例的文件夹下,修改redis-server的名称和配置内容
然后在对应的路径下使用
./redis-server6379 start|restart|stop
启动/重启/停止对应的redis服务
- 设置主节点和从节点
设置主节点不需要做什么操作,只需要对要被设置成从节点的节点进行设置。
首先是终端命令设置
通过redis-cli -h 节点ip -p 端口号 进入对应的redis
使用slaveof 主节点ip 端口号来将当前节点设置为主节点下的从节点。
但是,通过命令来设置的从节点在对应的服务重启后,和主节点之间的角色关系就会消失。所以要永久的保存这个主从关系,需要我们进入节点的redis.conf配置文件加上
slaveof 主节点ip 端口号
查看节点信息
127.0.0.1:6379> info replication
如果主节点下没有从节点,则connected_slave会显示0
也不会出现从节点的相关信息
- 验证结果
被设置为从节点的redis进行写操作是会提示你不能写,只能读
从节点读取key为name的数据,结果为空
主节点进行读写,写入key为name的数据
主节点更新后,从节点读取key为name的数据,显示为主节点写入的数据
主从复制中存在两种复制方式:全量同步、增量同步
全量同步:在从节点第一次链接主节点时,也就是slave从节点的初始化阶段。
- 从节点链接到主节点,向主节点发送SYNC命令。
- 主节点受到SYNC命令,触发执行bgsave命令生成RDB文件,并用缓冲区记录之后发生的所有写命令
- bgsave命令执行结束后,向所有的从节点发送RDB快照文件,并用缓冲区继续记录之后发生的所有写命令
- 从节点接到快照文件后,载入新数据,代替旧数据。
- 主节点向所有从节点发送后续缓冲区中的写命令
- 从节点完成快照文件的载入后,接受主节点的命令,执行这些写命令
增量同步:增量同步是指从节点初始化后正常工作运转时主节点发生的写入命令同步到从节点。
具体过程就是主节点会每执行一个写命令,就会将这个写命令发送给从节点,从节点接收并执行这些写命令。
主从复制实现了主节点和从节点读写分离,减少了主节点服务的压力。
哨兵模式
主从模式下,当主节点挂掉之后,我们需要用一台从节点的机器升级为master顶替原本的主节点。但是这需要我们去人工去更改从节点的配置,费时费力,也会导致相当一段时间服务不可用。所以我们在实际运用中,我们使用的时哨兵模式,我们会定义一个哨兵sentinel来监控master是否下线,如果判断下线,就会投票选举出一个slave从节点升级为master作为主节点。但是我们同样会担心哨兵挂掉,所以我们同样会对哨兵进行高可用集群操作,布置多个哨兵,哨兵之间相互监控,而且为了便于投票决策选举,我们会使用奇数个哨兵。
配置哨兵
Ubuntu下使用apt install redis-sentinel命令下载redis哨兵。
将/etc/redis路径下的sentinel.conf复制多份
将/etc/init.d路径下的redis-sentinel复制多份
修改配置
Sentinel.conf
# 哨兵ip地址
bind 0.0.0.0
# 哨兵端口号
port 36379
# pid文件地址
pidfile "/usr/local/redis-slave/sentinel/redis6379-sentinel.pid"
# 哨兵日志文件
logfile "/usr/local/redis-slave/sentinel/redis6379-sentinel.log"
# 监控 mymaster(主节点名/随便起的) 主节点的ip 主节点的端口号 经过投票后sentinel认为主节点挂掉的数量,此处为1
sentinel monitor mymaster 127.0.0.1 6381 1
#30秒ping不通主节点的信息,主观认为master宕机
sentinel down-after-milliseconds mymaster 30000
#故障转移后重新主从复制,1表示串行,>1并行
sentinel parallel-syncs mymaster 1
#故障转移开始,三分钟内没有完成,则认为转移失败
sentinel failover-timeout mymaster 180000
Redis-sentinel同redis-server类似
启动sentinel哨兵
./redis6379-sentinel start
验证结果
关闭主节点
- kill杀死主节点进程
- 进入主节点的redis服务,输入shutdown命令
127.0.0.1:6379> shutdown
- 关闭服务
service redis-server stop
再次重启主节点后,主节点会变成从节点的从节点,而从节点会变为主节点
相应节点的配置也会被哨兵修改,哨兵自身监控的主节点的配置也会变化
从节点变化
主节点变化
哨兵模式的原理
通过哨兵的log日志文件来分析一下
哨兵模式的主要原理就是,哨兵会对主节点进行监控,当主节点挂掉之后(这里称为下线),哨兵会进行投票从主节点的从节点中选举出一个来升级为master,直接将该节点的配置文件修改,并将之前主节点的其他从节点的配置文件修改,将这些从节点的主节点指向升级后的主节点(修改slaveof),原本的主节点重启之后,同样也会变为新主节点的从节点,哨兵还会将自身的监控对象修改为新的主节点。
这里由哨兵集群来监控主节点,每个哨兵会以每秒一次的频率向整个集群中主节点Master,从节点Slave以及其他的哨兵发送ping命令。
当有一个实例(master、slave或sentinel)距离最后一次有效回复ping命令的时间超过了配置中指定的超时时间,那么这个实例则会被这个哨兵标记为主观下线(也就是log日志文件中的-sdown)。
如果这个被标记为主观下线的实例时一个master,那么所有的哨兵都会以每秒一次的频率来确认这个master是否确认进入了主观下线的状态。
当有足够的哨兵都将这个master标记为了主观下线(足够数量指的是配置中指定的值),那么这个master就会被标记为客观下线(odown)
当一个master被标记为客观下线,哨兵将会把向集群中的maste节点、slave节点发送info命令的频率由10秒一次变成每秒一次。
当主观下线时,系统并不会马上进行故障转移(failover)选出新的master,但是一定数量的哨兵都检测到master不可用,那么这就是客观下线,哨兵们会进行一次投票,投票由第一个哨兵发起(也就是log文件中的+vote-for-leader),进行failover故障转移。