五大实例详解,携程 Redis 跨机房双向同步实践

前言在《携程 redis 跨 IDC 多向同步实践》一文曾和大家分享过携程在 Redis 双向同步方面的心得,简单介绍了实现一个 Redis 双向同步系统中可能面临的问题,以及其中一种问题(分布式一致性)的部分处理方案 -- CRDT(Conflict-free ReplicatedData Types) 。本文将进一步阐述在具体设计和落地过程中的一些细节,希望对大家能够有所帮助 。包括:

  • Cycle Break -- 如何打破盗梦空间的无限循环
  • Last Write Wins & Vector Clock -- 冲突的解决既简单又复杂
  • Tomstone -- 忆往昔才能看今朝
  • GC -- CRDT 取经之路的通天河
  • Expire -- 一致 or 不一致,这是个问题
相信通过对这些问题的描述和解答,大家对于如何实现一个双向同步的 Redis 会有一幅清晰的构图 。
一、Cycle Break -- 如何打破盗梦空间的无限循环1.1 复制回环
以下图为例,假设 A <-> B <-> C 三个 Redis 建立起了双向复制关系 。现在客户端先向其中一个 Redis(假设 A)发送了命令,SET KEY VAL(将 key 的值,设置或更新为 val),那么大概率会发生以下这样的步骤:
1)A 将 SET KEY VAL 同步至 B 和 C
2)B 和 C 接收到操作后,又再次同步给其他两个 Redis
3)如此循环往复 ...
综上所述,复制回环所带来的问题结合普通的数据结构,会带来以下问题:
  • 网络风暴
  • 数据不一致

五大实例详解,携程 Redis 跨机房双向同步实践

文章插图
 
1.2 如何解决
如何解决这个问题呢,无非以下几种方式:
1)在数据上做处理,使数据携带一定的信息,服务端通过对数据所携带信息的甄别,过滤掉冗余消息 。
2)在内容分发上做处理,服务端能够识别不同的链接类型,从而做到有的放矢,在同步数据之初便加以控制;
针对 Redis 这种场景,我们选择了第二种处理方案,既在复制数据的时候,根据数据来源的类型,来决策是否同步给其他 Redis 。
为了方便大家理解,这里简单介绍一下 Redis 的内部实现:Redis 对于每一个TCP链接,都会抽象成为一个叫 client 的对象,见下图 。而其中有一个 flag 表示了这个链接(client)对应的类型,这就很好地契合了上文中列举出的第二条选项 。
五大实例详解,携程 Redis 跨机房双向同步实践

文章插图
 
所以,我们最终的处理方案是:Redis对数据源进行甄别,只有属于来自客户端的操作,才会被选择性地同步给 Peer Master 。然而,对于传统的 Master-Slave 架构来讲,还是会把所有对数据库有变更的操作,都同步给 Slave 。
二、Last Write Wins & Vector Clock -- 冲突的解决既简单又复杂这里以一对简单的 K/V 为例,介绍下是如何处理冲突的 。
2.1 冲突是如何产生的
下面一幅图很好地诠释了,为什么会有冲突以及冲突的后果 。
假设我们在同一时刻,分别在两个互相同步的 Redis 上更新了一个 Key,左边的试图将 Key 设置为 CAT,而后边的客户端试图将 Key 设置为 DOG 。
那么总共会有以下 4 种结果,前两种虽然不尽如人意,但至少保证了数据的一致性 。而后面两种则是大家不希望看到的,因为数据不一致对业务造成不可忽略的风险 。
五大实例详解,携程 Redis 跨机房双向同步实践

文章插图
 
2.2 LWW -- Last Write Wins
其实解决这个问题也很简单,就是“最后写入为准”的原则 。以下图为例,假设两个 Redis 分别收到了对于同一个 Key 的设值需求,那么我们就可以简单地根据这个原则来判定,最终的结果是最后一次的写入为准 。
五大实例详解,携程 Redis 跨机房双向同步实践

文章插图
 
看到这里,大家也许会发现,原来冲突处理如此简单,那我也可以大展身手了 。当然,大部分系统的实现,做到这一层,已经解决了分布式一致性的问题 。但是,是不是这样就皆大欢喜了呢?
答案当然是否定的,继续往下看你就会发现,这小小的 K/V 一致性,只是分布式系统中的冰山一角 。冰山的下面有着千奇百怪的洪水猛兽,一个没处理到,都会带来无可估量的业务损失 。
2.3 时钟 -- 分布式系统永远的痛
相信部分同学在上学阶段或是工作以后,拜读过分布式系统的经典书目 --Distributed System Concept and Design (如下图) 。这本书在开篇就对分布式系统有了一个经典的定义:
  • Concurrency
  • No Global Clock
  • Independent Failures


推荐阅读