【Redis】主从复制相关配置和常见问题解决

星图妙赏 2019-09-11 16:55:11

序言

点击图像可以常看更多有关文章

1. 主从复制相关配置

主从复制的配置都是在从节点配置,所以以下几个参数都是在从节点配置

1、slaveof  <master ip> <master port>

slave实例需要配置该项,指向master的ip和port

2、masterauth <master-password>

如果master实例启用了密码,则该配置项需要填master的启动密码,若master未启用密码,该配置需要注释掉

3、slave-server-stale-data

指定slave与master连接中断时的动作,默认为yes,表明slave会继续应答来自client的请求,但这些数据可能已经过期(因为连接中断导致无法从master同步)。若配置为no,则slave除正常应答info和slaveof命令外,其余来自客户端请求的命令会均得到“sync with master in prigress”的应答,直到该slave与master的连接重建成功或改slave被提升为master

4、slave-read-only

指定slave是否只读,默认为yes。若配置为no,这表示slave是可写的,但是写的内容在主从同步后会被删除

5、repl-disable-tcp-nodelay

指向slave同步数据时,是否禁用scoket的NO_DELAY选项,若配置为yes则禁用NO_DELAY,则tcp协议栈会合并小包统一发送,这样可以减少主从节点间的包数量并节省宽带,但会增加数据同步到slave的时间。若配置为no,表明启用NO_DELAY,则tcp协议栈不会延迟小包的发送时机,这样数据同步的延时会减少,但需要更大的宽带,通常情况下,应该配置为no以降低同步延时,但在主从节点间网络负载已经很高的情况下, 可以配置为yes

6、slave-priority

指定slave的优先级,在不只1个salve存在的部署环境下,当master宕机时,redis sentinel会将priority值最小的slave提升为master,需要注意的是,若改配置项为0,则对应的slave永远不会被redis sentinel自动提升为master

2. 主从复制进阶常见问题解决2.1 读写分离

读流量分摊到从节点,这是个非常好的特性,如果一个业务只需要读数据,那么我们只需要连接一台slave从机读数据

虽然读写有优势,能够让读这部分分配给各个slave从机,如果不够,直接加slave机器就好了,但是也会出现以下问题

1、复制数据延迟

可能会出现slave延迟当值读写不一致等问题,当然你也可以使用监控偏移量offset,如果offset超出范围就切换到master上,逻辑切换,而具体延迟多少,可以通过info replication的offset指标进行排查

对于无法容忍大量延迟场景,可以编写外部监控程序(consul)监听主节点的复制偏移量,当延迟较大时触发报警或者通知客户端避免读取延迟过高的从节点

同时从节点的slave-serve-stale-data参数也与此有关,它控制这种情况下从节点的表现:如果为yes(默认值),则从节点仍能够响应客户端的命令;如果为no,则从节点只能响应info、slaveof等少数命令。该参数的设置与应用对数据一致性的要求有关;如果对数据一致性要求很高,则应设置为no。

2、只有n个从节点链接的时候才允许写入

redis2.8以后,可以设置从节点在有N台从节点链接的时候可以写入请求,然后因为redis使用的是异步复制,所以没有办法保证从节点确实收到的给定写入请求,所以存在一个窗口期的数据丢失的可能性。

下来解释一下这个特性是如何工作的

从节点每秒钟都会ping主节点,告知它所有的复制流工作了

主节点会记住每个从节点收到的最新的ping

用户可以给主节点配置一个在等于从节点的数量的最低值和不超过最高值之间的延迟

如果至少有N个从节点,如果少于延迟M秒,则写入就将被接受

你可能觉得经最大努力保证数据安全机制,虽然数据一致性无法保证,但是至少只是几秒的时间窗口内丢失数据,通常情况下范围数据丢失可比无范围数据丢失好多了

如果条件不满足,主节点将会返回一个错误,并且写入请求将不接受

主机配置两个参数:

最小的从主机连接数量

min-slaves-to-write <number of slaves>

最大的延迟时间

min-slaves-max-lag <number of seconds>

举个例子,如果我们向主服务器提供以下设置:

min-slaves-to-write 3min-slaves-max-lag 10

那么在从服务器的数量少于3个,或者三个从服务器的延迟(lag)值都大于或等于10秒时,主服务器将拒绝执行写命令

3、如何选择,要不要读写分离

没有最合适的方案,只有最合适的场景,读写分离需要业务可以容忍一定程度的数据不一致,适合读多写少的业务场景,读写分离,是为了什么,主要是因为要建立一主多从的架构,才能横向任意扩展slave node去支撑更大的读吞吐量

2.2从节点故障

对于从节点的故障问题,需要在客户端维护一个可用从节点可用列表,当从节点故障时,立刻切换到其他从节点或主节点,之后redis Cluster 时候可以解决这个问题

2.2.1配置不一致

主机和从机不同,经常导致主机和从机的配置不一致,并带来的问题

数据丢失:主机和从机有时候会发生配置不一致的情况,例如maxmemory不一致,如果主机配置maxmemory为8g,从机slave设置为4g,这个时候是可以用的,而且还不会报错。但是如果要做高可用,让从节点变成主节点的时候,就会发现数据已经丢失了,而且无法挽回

2.2.2规避全量复制

全量复制指的是当slave从机断掉并重启后,runid产生变化而导致需要在master主机里拷贝全部数据。这种拷贝全部数据的过程非常耗资源

全量复制是不可避免的,例如第一次的全量复制是不可避免的,这是我们需要选择小主节点且maxmemory值不要过大,这样就比较快。同时选择在低峰值的时候做全量复制

2.2.3造成全量复制的原因

1、主从节点运行的runid不匹配。主节点如果重启,runid将会发生变化。如果从节点监控到runid不是同一个,它就会认为你的节点不安全。当发生故障转移时候,如果主节点发生故障,那么从机就会变成主节点。后边会说到哨兵和集群

2、复制缓冲区空间不足,比如默认1M,可以部分复制。但如果缓冲区不够大的话,首先需要网络中断,部分复制就无法满足。其次需要增大复制缓冲区配置(relbacklogsize)对网络的缓冲增强

2.2.4解决全量复制

在一些场景下,可能希望对主节点进行重启,例如主节点内存碎片率过高,或者希望调整一些只能在启动时调整的参数。如果使用普通的手段重启主节点,会使得runid发生变化,可能导致不必要的全量复制

为了解决这个问题,Redis提供了debug reload的重启方式:重启后,主节点的runid和offset都不受影响,避免了全量复制。

例如:当一个主机下面挂了很多个slave从机的时候,主机master挂了,这时master主机重启后,因为runid发生了变化,所有的slave从机都要做一次全量复制。这将引起单节点和单机器的复制风暴,开销会非常大。

解决:

可以采用树状结构降低多个从节点对主节点的消耗

从节点采用树状树非常有用,网络开销交给位于中间层的从节点,而不必消耗顶层的主节点。但是这种树状结构也带来了运维的复杂性,增加了手动和自动处理故障转移的难度

2.2.5 单机风暴

由于 Redis 的单线程架构,通常单台机器会部署多个 Redis 实例。当一台机器(machine)上同时部署多个主节点(master)时,如果每个 master 主机只有一台 slave 从机,那么当机器宕机以后,会产生大量全量复制。这种情况是非常危险的情况,带宽马上会被占用,会导致不可用。

解决:

应该把主节点尽量分散在多台机器上,避免在单台机器上部署过多的主节点。

当主节点所在机器故障后提供故障转移机制,避免机器恢复后进行密集的全量复制

1 阅读:33