Redis分布式基础主从同步
Redis搭建主从同步读写分离实战
通过主从和读写分离我们可以保证即使Redis服务器宕机后,我们依然是可以正常使用Redis,这里只是保证可用,但是离高可用还有一段距离。
假如从服务器宕机了,还可以读另一台从服务器,那么要是主服务器挂了呢?通过读写分离,我们难以写入数据,当然我们可以重启主服务器,哈哈哈,但是,半夜三更主服务器宕机了呢?此时mango陷入深思。
所以在这种情况下,我们需要有一个监控系统,如果主服务器挂掉用我们可以使用其中一个从服务器代替主服务器,这样保证我们可以进行写操作。
Redis官方给我们提供了一种解决方案Sentinel翻译为哨兵,哨兵就是这样的,检测主从服务器的健康,如果发现主服务器宕机了,立即将一位从服务器升级成主服务器,保证集群正常工作。
Sentinel基本配置Sentinel的服务器和Redis的主从服务器是一样的,只不过Sentinel不需要保存数据只执行部分Redis的命令,下面我们来看看Sentinel的配置。
port 26379
1、Sentinel端口,默认端口26379
daemonize yes
2、是否后台启动
pidfile /var/run/redis-sentinel.pid
3、pid文件路径
logfile "/var/log/sentinel.log"
4、日志文件路径
dir /tmp
5、定义工作目录
sentinel monitor mymaster 127.0.0.1 6379 2
6、定义Redis主的别名, IP, 端口,这里的2指的是需要至少2个Sentinel认为主Redis挂了才最终会采取下一步行为
sentinel down-after-milliseconds mymaster 30000
7、如果mymaster 30秒内没有响应,则认为其主观失效
sentinel parallel-syncs mymaster 1
8、如果master重新选出来后,其它slave节点能同时并行从新master同步数据的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保守的设置为1,同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。
sentinel failover-timeout mymaster 180000
9、该参数指定一个时间段,在该时间段内没有实现故障转移成功,则会再一次发起故障转移的操作,单位毫秒
sentinel deny-scripts-reconfig yes
10、不允许使用SENTINEL SET设置notification-script和client-reconfig-script。
哨兵的作用
监控:监控主节点和从节点是否正常运行,主节点和从节点运行情况。
自动转移故障:当检测到主节点宕机后,断开与宕机主节点连接的所有从节点,在从节点中选取一个作为主节点,然后将其他的从节点连接到这个最新主节点的上。
通知:哨兵检测的服务器出现问题时,会向其他的哨兵发送通知,此处使用的是发布订阅方式,只需要在此频道发送通知,其他哨兵立即接收到通知,转移故障后并且通知客户端新的主节点的地址。
自动转移故障过程Sentinel持续监控Redis的主从服务器,当主服务器宕机,如果有多个Sentinel的情况下,首先发送通知给其他Sentinel服务器,选举出一个主Sentinel,然后主Sentinel通过从服务器的优先顺序选择一个最佳的从服务器升级成主服务器。
最后将这个消息通知到客户端(这里的客户端是指调用Redis服务的那端,一般是站点服务器)和其他的Sentinel节点上。
切换Redis主服务器后,Redis内部依然正常运作,客户端无需知道集群内部如何切换,只需要从Sentinel中询问到新的主从服务器地址即可,我们的运维工程师也无需每时每刻盯着服务器,这样就完成了故障转移。
Redis恢复过程mango同学问:那刚刚掉线的那个主服务器恢复正常后如何处理呢?是否还恢复他主服务器的位置呢?
当服务器恢复正常后,Sentinel检测到新的节点加入,立即发送通知告诉它主服务器地址,然后通过这个地址请求同步数据。
这个节点恢复后是从节点,我们试想,如果说此节点恢复后立即恢复它主节点的位置,那么之前加入过的数据为了保证数据安全,先得从最新主节点同步然后恢复它主节点位置,绕了一大圈,并没有什么意义,而且操作复杂服务器性能受到影响。
客户端处理地址变更1、当Sentinel进行主从切换时,客户端如何知道地址变更了?
连接池建立新连接时,会去查询主节点地址,然后跟内存中的主节点地址进行
比对,如果变更了,就断开所有连接,重新使用新地址建立新连接。
2、当客户端已经连接到服务器,此时Redis服务器与Sentinel断开连接,Sentinel主动进行主从切换,但主节点并没有挂掉,而之前的主节点连接已经建立了且在使用中,没有新连接需要建立,那么这个连接是不是一直切换不了?
当然,在旧的主服务器与Sentinel成功连接后发送新的主服务器地址给它,此时接收到降级的指令,处理命令的时候捕获了一个异常ReadOnlyError,在这个异常里将所有的旧连接全部关闭了,后续指令就会进行重连。
但是如果说旧服务器还没有接受到这个命令时,它或多或少是可以写入数据的,此时其他的服务器没有接收到这个数据的写入,问题来了,数据产生了丢失,这就是任何集群项目中都会出现的脑裂问题,我会在下一篇文章中与大家一起探讨此问题。
总结一下:首先我们要了解哨兵是在Redis主从的基础上继续达到高可用的一个解决方案,哨兵主要的工作就是监控、发通知、故障转移。通过故障转移我们可以进行读写,客户端无需关系Redis集群内部如何实现,只关心读写数据,最后我们了解了Redis的恢复过程,旧的主服务器恢复后成为从服务器,请求主服务器同步数据。
一名正在抢救的coder
笔名:mangolove
CSDN地址:https://blog.csdn.net/mango_love
GitHub地址:https://github.com/mangoloveYu