redis之主从问题处理

主从复制的常用相关配置

  • Slaveof

    slaveof

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

  • masterauth

    masterauth

    如果master实例启用了密码保护,则该配置项需要填master的启动密码;

    如果未启用,需要将该配置项注视掉。

  • slave-serve-stale-data

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

  • slave-read-only

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

  • repl-disable-tcp-nodelay

    指定向slave同步数据时,是否禁用socketNO_DELAY选项。若配置为yes,则禁用NO_DELAY,则TCP协议栈会合并小包统一发送,这样可以减少主从节点间的包数量并节省宽带,但会增加数据同步到slave的时间。若配置为no,表明启用NO_DELAY,则TCP协议栈不会延迟小包的发送时间,这样数据同步的延时会减少,但需要更大的宽带。

  • slave-priority

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

读写分离

复制数据延迟

Redis复制数据的延迟由于异步复制特性是无法避免的,延迟取决于网络宽带和命令阻塞情况,比如刚在主节点写入数据后立刻在从节点上读取可能获取不到。需要业务场景允许短时间内的数据延迟。对于无法容忍大量延迟场景,可以编写外部监控程序监听主从节点的复制偏移量,当延迟较大时触发报警或通知客户端避免读取延迟过高的从节点。

具体实现逻辑:

  • 监控程序定期检查主从节点的偏移量,主节点偏移量在info replicationmaster_repl_offset指标记录,从节点偏移量可以查询主节点的slave0字段的offset指标,它们的差值就是主从节点延迟的字节量。
  • 对于无法容忍大量延迟场景,可以编写外部监控程序监听主从节点的复制偏移量,当延迟较大时触发报警或者通知客户端避免读取延迟过高的从节点,同时从节点的slave-serve-stable-data参数也与此有关,它控制这种情况下从节点的表现,当从库同主机失去连接或者复制正在进行,从机库有两种运行方式。

读取过期数据

当主节点存储大量设置超时的数据时,redis内部需要维护过期数据删除策略,删除策略主要有两种:

  • 惰性删除

    主节点每次处理读取命令时,都会检查健是否超时,如果超时则执行·del命令删除键对象,之后del命令也会异步发给从节点。因为保持复制的一致性,从节点自身永远不会主动删除超时数据。

  • 定时删除

    Redis主节点在内部定时任务会循环采样一定数据量的键,当发现采用的键过期时会执行del命令,之后再同步给从节点。

从节点故障问题

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

配置不一致

主节点和从节点不同,经常导致主节点和从节点的配置不同,并带来问题。

主从配置不一致是一个容易忽视的问题。对于有些配置主从之间是可以不一致,比如:主节点关闭AOF,从节点开启AOF。但对于内存相关的配置必须要一致,比如maxmemory,hash-max-ziplist-entries等参数。

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

规避全量复制

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

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

造成全量复制的原因:

  • 主从机的运行runid不匹配。解释一下,主节点如果重启,runid将会发生变化。如果从节点监控到runid不是同一个,它就会认为你的节点不安全。当发生故障转移的时候,如果主节点发生故障,那么从节点就会变成主节点(哨兵和集群)。
  • 复制缓冲区空间不足,比如默认值为1M,可以部分复制,但如果缓冲区不够大的话,首先需要网络中断,部分复制将无法满足。其次需要增大复制缓冲区配置repl-backlog-size,对网络的缓冲增强。

怎么解决:

  • 在一些场景下,可能希望对主节点进行重启,例如主节点内存碎片率过高,或者希望调整一些只能在启动时调整的参数。如果使用普通的手段重启主节点,会使得runid发生变化,可能导致不必要的全量复制。
  • 为了解决这个问题,Redis提供了debug reload的重启方式:重启后,主节点的runidoffset都不受影响,避免了全量复制。

规避复制风暴

复制风暴是指大量从节点对同一主节点或者对同一台机器的多个主节点短时间内发起全量复制的过程。复制风暴对发起复制的主节点或者机器造成大量开销,导致 CPU、内存、带宽消耗。因此我们应该分析出复制风暴发生的场景,提前采用合理的方式规避。规避方式有如下几个。

单节点复制风暴

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

解决:

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

单机器复制风暴

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

解决:

  • 应该把主节点尽量分散在多台机器上,避免在单台机器上部署过多的主节点。
  • 当主节点所在机器故障后提供故障转移机制,避免机器恢复后进行密集的全量复制。
image

补充

###########从库##############

#设置该数据库为其他数据库的从数据库

slaveof

#主从复制中,设置连接master服务器的密码(前提master启用了认证)

masterauth

# 当从库同主库失去连接或者复制正在进行,从库有两种运行方式:

# 1) 如果slave-serve-stale-data设置为yes(默认设置),从库会继续相应客户端的请求

# 2) 如果slave-serve-stale-data设置为no,除了INFOSLAVOF命令之外的任何请求都会返回一个错误"SYNC with master in progress"

slave-serve-stale-data yes

#当主库发生宕机时候,哨兵会选择优先级最高的一个称为主库,从库优先级配置默认100,数值越小优先级越高

slave-priority 100

#从节点是否只读;默认yes只读,为了保持数据一致性,应保持默认。

slave-read-only yes

########主库配置##############

#在slavemaster同步后(发送psync/sync),后续的同步是否设置成TCP_NODELAY假如设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟(40ms),造成masterslave数据不一致假如设置成no,则redis master会立即发送同步数据,没有延迟。

#前者关注性能,后者关注一致性

repl-disable-tcp-nodelay no

#从库会按照一个时间间隔向主库发送PING命令来判断主服务器是否在线,默认是10秒

repl-ping-slave-period 10

#复制积压缓冲区大小设置

repl-backlog-size 1mb

#master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度。单位为秒。

repl-backlog-ttl 3600

#redis提供了可以让master停止写入的方式,如果配置了min-slaves-to-write,健康的slave的个数小于Nmater就禁止写入。master最少得有多少个健康的slave存活才能执行写命令。这个配置虽然不能保证Nslave都一定能接收到master的写操作,但是能避免没有足够健康的slave的时候,master不能写入来避免数据丢失。设置为0是关闭该功能。

min-slaves-to-write 3

min-slaves-max-lag 10

你可能感兴趣的:(redis之主从问题处理)