在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡灯需求。Redis提供了复制功能,实现了相同数据多个副本,复制功能作是高可用Redis的基础,深入理解复制的工作原理与使用技巧对我们日常开发运维非常有帮助。
1. 配置
1.1 建立复制
每个从节点只能有一个主节点,而主节点可以同时具有多个从节点。复制的数据流是单向的,只能由主节点复制到从节点。
配置复制的三种方式:
- 配置文件中键入 slaveof {masterHost} {masterPort},随Redis启动生效
- 在 redis-server 启动命令后加入 --slaveof {masterHost} {masterPort}
- 直接使用命令:slaveof {masterHost} {masterPort}
可以使用 info replication 命令查看复制相关状态
1.2 断开复制
在从节点执行 slaveof no one 来断开与主节点的复制关系;从节点断开复制关系后并不会删除原有的数据。
1.3 切换主节点
执行 slaveof {newMasterHost} {newMasterPort}
切换主节点流程:
- 断开与旧主节点的复制关系
- 与新主节点建立复制关系
- 删除从节点当前所有数据(*)
- 对新主节点进行复制操作
1.4 安全性
主节点可以通过设置 requirepass 参数进行密码验证,从节点需要配置 masterauth 参数与主节点密码保持一致,这样从节点才可以正确的链接到主节点并发起复制流程。
1.5 只读
默认情况下,从节点使用 slave-read-only=yes 配置为只读模式。
因为复制只能从主节点到从节点,修改从节点造成主从数据不一致,因此,线上环境从节点一般设置为只读模式。
1.6 传输延迟
主从节点一般部署在不同机器上,复制时的网络延迟就成为需要考虑的问题,Redis提供了 repl-disable-tcp-nodelay 参数用于控制是否关闭 TCP_NODELAY,默认关闭。
- 关闭时,主节点产生的命令数据无论大小都会及时地发送到从节点,这样网络延迟会变小,但增加了网络带宽的消耗。适用于主从之间的网络环境良好的场景,如同机架或者同机房。
- 开启时,主节点会合并较小的TCP数据包从而节省带宽,但会增大主从之间的延迟。适用于主从网络环境复杂或者带宽紧张的场景。
2. 拓扑
Redis 复制拓扑结构支持单层或者多层复制关系,可分为三种:
- 一主一从
- 一主多从
- 树状主从结构
2.1 一主一从结构
用于主节点宕机时从节点提供故障转移支持。
当应用写命令并发量较高且需要持久化时,可以只在从节点上开启AOF,这样既保证了数据安全性也避免了持久化对主节点的性能干扰。
注意:
若主节点关闭了持久化功能,主节点脱机要避免自动重启,不然主节点因为没有持久化自动重启后数据库为空,此时从节点继续复制主节点会导致从节点数据库也被清空。
安全的做法:从节点上执行 slaveof no one 断开与主节点的复制关系,再重启主节点从而避免这一问题。
2.2 一主多从结构
一主多从结构可以使得应用可以利用多个从节点实现读写分离。
- 对于读占比比较大的场景,可以把读命令发送到从节点来分担主节点压力。
- 对于写并发量较高的场景,多个从节点会导致主节点写命令的多次发送从而过度消耗网络带宽,同时也加重了主节点的负载。
2.3 树状主从结构
树状主从结构引入了复制中间层,有效降低了主节点负载和需要传送的从节点数量。
3. 复制
Redis 的复制过程分为 同步(sync)和 命令传播
同步过程又分为:完整重同步(全量复制)和部分重同步(部分复制)
- 完整重同步:用于处理初次复制的情况,主服务器将全部数据写入RDB文件并一次性发送给从服务器
- 部分重同步:用于处理断线后重复制的情况,当从服务器重新连接上主服务器后,如果条件允许,主服务器可以只补发丢失数据给从节点。
4. 基于复制的应用场景中应该注意的问题
通过复制机制,数据集可以存在多个副本,这些副本可以应用于读写分离、故障转移(failover)、实时备份等场景。
实际应用复制功能时,需要注意的坑:
4.1 读写分离
读占比比较高的场景,通过把一部分读流量分摊到从节点来减轻主节点的压力。
当使用从节点响应读请求时,业务端可能会遇到如下问题:
- 复制数据延迟
- Redis复制数据的延迟由于异步复制特性无法避免,延迟取决于网络带宽和命令阻塞情况。
- 读到过期数据
- 从节点故障
综上所述,使用Redis做读写分离有一定的成本,开发人员在使用额外的从节点提升读性能前,可以尽量在主节点上做充分优化,比如解决慢查询,持久化阻塞、合理应用数据结构。另外,可以考虑 Redis Cluster 等分布式解决方案,既可以扩展读性能还可以扩展写性能和可支撑数据规模,并且一致性和故障转移也得到保证。
... 未完待续