Redis 聊聊主从复制需要注意的几个方面

网友投稿 728 2022-09-04

Redis 聊聊主从复制需要注意的几个方面

Redis 聊聊主从复制需要注意的几个方面

数据同步

Redis在2.8及以上版本使用psync命令完成主从数据同步, 同步过程分为: 全量复制和部分复制。· 全量复制: 一般用于初次复制场景, Redis早期支持的复制功能只有全量复制, 它会把主节点全部数据一次性发送给从节点, 当数据量较大时, 会对主从节点和网络造成很大的开销。

· 部分复制: 用于处理在主从复制中因网络闪断等原因造成的数据丢失场景, 当从节点再次连上主节点后, 如果条件允许, 主节点会补发丢失数据给从节点。 因为补发的数据远远小于全量数据, 可以有效避免全量复制的过高开销。部分复制是对老版复制的重大优化, 有效避免了不必要的全量复制操作。 因此当使用复制功能时, 尽量采用2.8以上版本的Redis。

psync命令运行需要以下组件支持:·主从节点各自复制偏移量。 ·主节点复制积压缓冲区。 ·主节点运行id。

复制偏移量

参与复制的主从节点都会维护自身复制偏移量。 主节点(master) 在处理完写入命令后, 会把命令的字节长度做累加记录, 统计信息在info relication中的master_repl_offset指标中:(主节点查看)

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=127.0.0.1,port=6380,state=online,offset=2478,lag=0.................................................master_repl_offset:2478

从节点(slave) 每秒钟上报自身的复制偏移量给主节点, 因此主节点也会保存从节点的复制偏移量, 统计指标如下:(主节点查看)

127.0.0.1:6379> info replication# Replicationrole:masterconnected_slaves:1slave0:ip=127.0.0.1,port=6380,state=online,offset=2478,lag=0 --偏移量2478...................................................

从节点在接收到主节点发送的命令后, 也会累加记录自身的偏移量。 统计信息在info relication中的slave_repl_offset指标中:(从节点查看)

127.0.0.1:6380> info replication# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:up...............................................slave_repl_offset:2674

复制偏移量的维护如图所示。通过对比主从节点的复制偏移量, 可以判断主从节点数据是否一致。

运维提示:可以通过主节点的统计信息, 计算出master_repl_offset - slave_offset字节量, 判断主从节点复制相差的数据量, 根据这个差值判定当前复制的健康度。 如果主从之间复制偏移量相差较大, 则可能是网络延迟或命令阻塞等原因引起。

复制积压缓冲区

复制积压缓冲区是保存在主节点上的一个固定长度的队列, 默认大小为1MB, 当主节点有连接的从节点(slave) 时被创建, 这时主节点(master)响应写命令时, 不但会把命令发送给从节点, 还会写入复制积压缓冲区, 如图所示:

由于缓冲区本质上是先进先出的定长队列, 所以能实现保存最近已复制数据的功能, 用于部分复制和复制命令丢失的数据补救。 复制缓冲区相关统计信息保存在主节点的info replication中:

127.0.0.1:6379> info replication# Replicationrole:master...repl_backlog_active:1 // 开启复制缓冲区repl_backlog_size:1048576 // 缓冲区最大长度repl_backlog_first_byte_offset:7479 // 起始偏移量, 计算当前缓冲区可用范围repl_backlog_histlen:1048576 // 已保存数据的有效长度。

根据统计指标, 可算出复制积压缓冲区内的可用偏移量范围: [repl_backlog_first_byte_offset,repl_backlog_first_byte_offset+repl_backlog_histlen]。

主节点运行ID

每个Redis节点启动后都会动态分配一个40位的十六进制字符串作为运行ID。 运行ID的主要作用是用来唯一识别Redis节点, 比如从节点保存主节点的运行ID识别自己正在复制的是哪个主节点。 如果只使用ip+port的方式识别主节点, 那么主节点重启变更了整体数据集(如替换RDB/AOF文件),从节点再基于偏移量复制数据将是不安全的, 因此当运行ID变化后从节点将做全量复制。 可以运行info server命令查看当前节点的运行ID:

127.0.0.1:6379> info server# Serverredis_version:3.0.7...run_id:545f7c76183d0798a327591395b030000ee6def9

需要注意的是Redis关闭再启动后, 运行ID会随之改变, 例如执行如下命令:

# redis-cli -p 6379 info server | grep run_idrun_id:545f7c76183d0798a327591395b030000ee6def9# redis-cli -p shutdown# redis-server redis-6379.conf# redis-cli -p 6379 info server | grep run_idrun_id:2b2ec5f49f752f35c2b2da4d05775b5b3aaa57ca

如何在不改变运行ID的情况下重启呢?当需要调优一些内存相关配置, 例如: hash-max-ziplist-value等, 这些配置需要Redis重新加载才能优化已存在的数据, 这时可以使用debug reload命令重新加载RDB并保持运行ID不变, 从而有效避免不必要的全量复制。 命令如下:

# redis-cli -p 6379 info server | grep run_idrun_id:2b2ec5f49f752f35c2b2da4d05775b5b3aaa57ca# redis-cli debug reloadOK# redis-cli -p 6379 info server | grep run_idrun_id:2b2ec5f49f752f35c2b2da4d05775b5b3aaa57ca

运维提示: debug reload命令会阻塞当前Redis节点主线程, 阻塞期间会生成本地RDB快照并清空数据之后再加载RDB文件。 因此对于大数据量的主节点和无法容忍阻塞的应用场景, 谨慎使用。

psync命令

从节点使用psync命令完成部分复制和全量复制功能, 命令格式:psync{runId}{offset}, 参数含义如下: ·runId: 从节点所复制主节点的运行id。 ·offset: 当前从节点已复制的数据偏移量。

流程说明: 1) 从节点(slave) 发送psync命令给主节点, 参数runId是当前从节点保存的主节点运行ID, 如果没有则默认值为?, 参数offset是当前从节点保存的复制偏移量, 如果是第一次参与复制则默认值为-1。 2) 主节点(master) 根据psync参数和自身数据情况决定响应结果: ·如果回复+FULLRESYNC{runId}{offset}, 那么从节点将触发全量复制流程。 ·如果回复+CONTINUE, 从节点将触发部分复制流程。 ·如果回复+ERR, 说明主节点版本低于Redis2.8, 无法识别psync命令,从节点将发送旧版的sync命令触发全量复制流程。

对应的日志如下:

Connecting to MASTER 192.168.75.136:6379MASTER <-> REPLICA sync startedNon blocking connect for SYNC fired the event. --开始非阻塞同步Master replied to PING, replication can continue...Partial resynchronization not possible (no cached master)Full resync from master: 74fb29643971834fdf701beb1708ce9ddc23bdee:0 --全量同步MASTER <-> REPLICA sync: receiving 193 bytes from master --接受数据MASTER <-> REPLICA sync: Flushing old data --清空以前缓存得数据MASTER <-> REPLICA sync: Loading DB in memory --加载数据库到内存MASTER <-> REPLICA sync: Finished with success --完成同步

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Shell (()) 括号对整数进行数学运算
下一篇:Laravel 底层是如何处理 HTTP 请求的?(laravel文档)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~