在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障恢复和负载均衡灯需求。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 等分布式解决方案,既可以扩展读性能还可以扩展写性能和可支撑数据规模,并且一致性和故障转移也得到保证。

... 未完待续

《Redis设计与实现》- 复制的更多相关文章

  1. Redis | 第11章 服务器的复制《Redis设计与实现》

    目录 前言 1. 旧版复制功能的实现 1.1 同步与命令传播 1.2 旧版复制功能的缺陷 2. 新版复制功能的实现 2.1 部分重同步的实现原理 3. PSYNC 命令的实现 4. 复制的详细步骤 4 ...

  2. Redis设计与实现(一~五整合版)【搬运】

    Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...

  3. Redis的主从同步复制

    先来看一下Redis的主从同步复制的原理: 在Slave启动并连接到Master之后,它将主动发送一条SYNC命令.此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台 ...

  4. 重读redis设计与实现

    重读了一遍redis设计与实现,这次收获也不错,把之前还有些疑惑的点:redis跳跃表的原理.redis持久化的方法.redis复制.redis sentinel.redis集群等,都重新熟悉了一遍, ...

  5. 《Redis设计与实现》

    <Redis设计与实现> 基本信息 作者: 黄健宏 丛书名: 数据库技术丛书 出版社:机械工业出版社 ISBN:9787111464747 上架时间:2014-6-3 出版日期:2014 ...

  6. Redis 之深入江湖-复制原理

    一.前言 上一篇文章Redis 之复制-初入江湖中,讲了关于Redis复制配置,如:如何建立配置.如何断开复制.关于链接的安全性等等,那么本篇文章将深入的去说一下关于Redis复制原理,如下: 复制过 ...

  7. 探索Redis设计与实现13:Redis集群机制及一个Redis架构演进实例

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  8. 探索Redis设计与实现12:浅析Redis主从复制

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  9. 探索Redis设计与实现11:使用快照和AOF将Redis数据持久化到硬盘中

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  10. 探索Redis设计与实现9:数据库redisDb与键过期删除策略

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

随机推荐

  1. css内容整理2

    10.6.css伪类.伪元素 伪类用于向某些选择器添加特殊效果:伪元素用于将特殊的效果添加达到某选择器. 区别:伪类的效果可通过添加一个实际的类达到,用::伪元素效果则需要添加一个实际的元素,用:: ...

  2. 【补充】docker基础学习

    docker 基础知识 之前写了一篇docker未授权访问的文章,现在来补充一下docker基础知识,以便更好的学习docker上的漏洞. docker是一款轻量级的虚拟化的产品,它属于层级化的架构. ...

  3. Object公用方法

    Object是所有类的父类,任何类都默认继承Object. Object类到底实现了哪些方法?   1.clone方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否 ...

  4. ssh无法连接到虚拟机linux系统

     一般ssh连不上虚拟机是防火墙没有放行22端口,用如下命令:(安装ssh服务时应该是放行了22端口的,如果没有则需手动放行22端口)   放行22端口: sudo iptables -I INPUT ...

  5. Hibernate课程 初探一对多映射3-2 单向多对一的配置

    1 多方实体类中加入,一方类和getset方法 //多方定义一个一方的引用 private Grade grade; public Grade getGrade() { return grade; } ...

  6. 粗看ES6之字符串

    标签: javascript es6 字符串新增特性 新增二个方法 - startsWith/endsWith 字符串模板 - 反单引号的应用 startsWith 判断字符串以是否以某某开头,返回一 ...

  7. iOS开发之Objective-c的AES256加密和解密算法的实现

    原文:http://www.lidaren.com/archives/1470 高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法. 以下实现 ...

  8. X-Cart-5.3.1.4 (Ubuntu 16.04)

    平台: Ubuntu 类型: 虚拟机镜像 软件包: x-cart-5.3.1.4 commercial ecommerce open-source x-cart 服务优惠价: 按服务商许可协议 云服务 ...

  9. Java I/O 工作机制(一) —— Java 的 I/O 类库的基本架构

    Java 的 I/O 类库的基本架构 Java 的 I/O 操作类在包 java.io 下,有将近 80 个类. 按数据格式分类: 面向字节(Byte)操作的 I/O 接口:InputStream 和 ...

  10. TP5.0: 显示错误信息

    在TP5中,我们运行的代码有错误无法执行时,只显示页面错误,而不显示错误信息 对我我来讲是无法接受滴!!毕竟我还是个小渣渣,查看了百度,解决方案是: 在application/config,php中找 ...