GMTC北京站两周后开幕,58个议题全部上线,点击查看 了解详情
写点什么

阿里数据一致性实践:Dledger 技术在消息领域的探索和应用

作者:刘振东

2019 年 3 月 04 日

阿里数据一致性实践:Dledger 技术在消息领域的探索和应用

一直以来,在多地多中心的消息发送场景下,如何保障数据的完整性和一致性是一个技术难点。本文将和您一起探讨 Dledger 技术,并分享 RocketMQ 的实践。


1. 多副本技术的演进

1.1 Master/Slave

多副本最早的是 Master/Slave 架构,即简单地用 Slave 去同步 Master 的数据,RocketMQ 最早也是这种实现。分为同步模式(Sync Mode)和异步模式(Async Mode),区别就是 Master 是否等数据同步到 Slave 之后再返回 Client。这两种方式目前在 RocketMQ 社区广泛使用的版本中都有支持,原理图如下图 1 所示。



图 1 Master-Slave


1.2 基于 Zookeeper 服务

随着 Google 三篇核心技术论文的发表(MapReduce、GFS 和 BigTable),分布式领域开启了快速发展。在 Hadoop 生态中,诞生了一个基于 Paxos 算法选举 Leader 的分布式协调服务 ZooKeeper。[z1] 由于 ZooKeeper 本身拥有高可用和高可靠的特性,随之诞生了很多基于 ZooKeepe r 的高可用高可靠的系统。具体做法如下图 2 所示:



图 2 Based on Zookeeper/Etcd


如图所示,假如系统里有 3 个节点,通过 ZooKeeper 提供的一些接口,可以从 3 个节点中自动的选出一个 Master 来。选出一个 Master 后,另外两个没成功的就自然变成 Slave。选完之后,后续过程与传统实现方式中的复制一样。故基于 ZooKeeper 的系统与基于 Master/Slave 系统最大的区别就是:选 Master 的过程由手动选举变成依赖一个第三方的服务(比如 ZooKeeper 或 Etcd)的选举。


基于 ZooKeeper 的服务还存在一个变种,具体做法如下图 3:



图 3 Based on ZooKeeper/Etcd


在第一种方式中,发起者(Client)和接收者(Server)都是在同一个进程中的。而在这种方式中 Client 是脱离于 Server 之外的,通过 Zookeeper,从这三个 Client 中选出一个 Master 来,选完 Master 后把请求同时发送到 3 个 Server 里,这样也可以达到多副本的效果。


但是基于 ZooKeeper 的服务也带来一个比较严重的问题:依赖加重。因为运维 ZooKeeper 是一件很复杂的事情。


1.3 基于 Raft 服务方式

因为 ZooKeeper 的复杂性,又有了以下 Raft 的方式。Raft 可以认为是 Paxos 的简化版。基于 Raft 的方式如下图 4 所示,与上述两种方式最大的区别是:leader 的选举是由自己完成的。比如一个系统有 3 个节点,这 3 个节点的 leader 是利用 Raft 的算法通过协调选举自己去完成的,选举完成之后,Master 到 Slave 同步的过程仍然与传统方式类似。最大的好处就是去除了依赖,即本身变得很简单,可以自己完成自己的协调。



图 4 Raft


  • Raft Leader Election 机制


Raft 最大的好处就是可以实现自身 leader 选举。如果一个分布系统要自我协调,通常是采用“投票”的方式,在“投票”的时候,为了解决冲突问题,就采用了两个机制:Term 和 Quorum。


  • Term,即给每一次投票编号,以 1、2、3 这样的数字命名。

  • Quorum,即少数服从多数原则,每一次投票必须要得到多数派(N/2 + 1)的同意才认为是成功。


根据这两个机制,在一个 Term 中,一个节点只能投出一票,保证在一个 Term 中只有一个节点能选举成功。如果在一个 Term 中,没有节点获得大多数节点(N/2+1)的选票,选举失败,会重新发起选举。选举失败后,给每个节点设置合适的随机等待时间,会容易更快选举完成。选举成功之后就是跟之前比较相似的复制过程。


  • 三种实现高可靠和高可用的方法优劣对比


Master/Slave,Based on ZooKeeper/Etcd 和 Raft,这三种是目前分布式系统中,做到高可靠和高可用的基本的实现方法,各有优劣。


  • Master/Slave


优点:实现简单


缺点:不能自动控制节点切换,一旦出了问题,需要人为介入。


  • Based on Zookeeper/Etcd


优点:可以自动切换节点


缺点:运维成本很高,因为 ZooKeeper 本身就很难运维。


  • Raft


优点:可以自己协调,并且去除依赖。


缺点:实现 Raft,在编码上比较困难。


2. 什么是 DLedger

2.1 Dledger 的定位

前文介绍了目前分布式系统中,做到高可靠和高可用的三种基本的实现方法。Raft 算法现在解析的比较多,也比较成熟,代码实现难度也有所降低。Dledger 作为一个轻量级的 Java Library,它的作用就是将 Raft 有关于算法方面的内容全部抽象掉,开发人员只需要关心业务即可。



图 5 Dledger Proposition


如上图所示,Dledger 只做一件事情,就是 CommitLog。Etcd 虽然也实现了 Raft 协议,但它是自己封装的一个服务,对外提供的接口全是跟它自己的业务相关的。在这种对 Raft 的抽象中,可以简单理解为有一个 StateMachine 和 CommitLog。CommitLog 是具体的写入日志、操作记录,StateMachine 是根据这些操作记录构建出来的系统的状态。在这样抽象之后,Etcd 对外提供的是自己的 StateMachine 的一些服务。Dledger 的定位就是把上一层的 StateMachine 给去除,只留下 CommitLog。这样的话,系统就只需要实现一件事:就是把操作日志变得高可用和高可靠。


这样做对消息系统还有非常特别的含义。消息系统里面如果还采用 StateMachine + CommitLog 的方式,会出现 double IO 的问题,因为消息本省可以理解为是一个操作记录。所以 Dledger 会提供一些对原生 CommitLog 访问的 API。通过这些 API 可以直接去访问 CommitLog。这样的话,只需要写入一次就可以拿到写入的内容。Dledger 对外提供的是简单的 API,如下图 6 所示。可以把它理解为一个可以无限写入操作记录的文件,可以不停 append,每一个 append 的记录会加上一个编号。所以直接去访问 Dledger 的话就是两个 API:一个是 append,另一个是 get,即根据编号拿到相应的 entry(一条记录)。



图 6 Dledger API


2.2 Dledger 的架构

Dledger 的架构如下图 7 所示:



图 7 Dledger Architecture


从前面介绍的多副本技术的历史可以知道,我们要做的主要有两件事:选举和复制,对应到上面的架构图中,也就是两个核心类:DLedgerLeaderElector 和 DLedgerStore,选举和文件存储。选出 leader 后,再由 leader 去接收数据的写入,同时同步到其他的 follower,这样就完成了整个 Raft 的写入过程。


2.3 Dledger 的代码

因为 Dledger 只有 CommitLog,没有 StateMachine,所以代码很精简,只有 4000 多行,总体代码测试覆盖率大概是 70%。通过如下几行命令便可以快速地体验:



图 8 Dledge Quick Start


Dledger 源代码地址:https://github.com/openmessaging/openmessaging-storage-dledger


3. RocketMQ on DLedger

3.1 Dledger 在 RocketMQ 上的应用


图 9 RocketMQ on Dledger Architecture


Dledger 虽然只需要写 CommitLog,但是基于 CommitLog 是可以做很多事情的。RocketMQ 原来的架构里是有 CommitLog 的,现在用 Dledger 去替代原来的 CommitLog。由于 Dledger 提供了一些可以直接读取 CommitLog 的 API,于是就可以很方便地根据 CommitLog 去构建 ConsumerQueue 或者其他的模块。这就是 Dledger 在 RocketMQ 上最直接的应用。


3.2 Dledger 与 RocketMQ 对接时格式上的区别:

加了 Dledger 之后,其实就是在原来的消息上面加了一个头。这个头就是 Dledger 的头,本质上是一些简单的属性,例如 size 等。如下图 10 所示。



图 10 RocketMQ on Dledger Format


在使用的时候会有格式上的差异,所以社区在升级的时候做了一个平滑升级的考虑,如图 11 所示。要解决的问题是:如何将原来已有的 CommitLog 和现在基于 Dledger 的 CommitLog 混合?现在已经支持自动混合,但是唯一的一个要求是旧版的 CommitLog 需要自己去保持它的一致性。因为 Dledger 的复制是从新写入的记录开始。假设旧的 CommitLog 已经是一致的情况下,然后直接启动 Dledger ,是可以在旧的 CommitLog 基础上继续 append,同时保证新写消息的一致性,高可靠和高可用。这是 Dledger 直接应用到 RocketMQ 上的时候一个格式上的区别。



图 11 RocketMQ on Dledger Smooth Upgrade


对于用户来说,这样做最直接的好处是:若使用 Master/Slave 架构模式,一旦一个 broker 挂了,则需要手动控制。但是使用 Dledger 之后不需要这么做。因为 Dledger 可以通过自己选举,然后把选举结果直接传给 RocketMQ 的 broker,这样通过 nameserver 拿到路由的时候就可以自动找到 leader 节点去访问消息,达到自动切换的目的。如下图 12 所示。



图 12 RocketMQ on Dledger Failover


3.3 Dledger 在多中心场景下的使用

上面只是最基本的应用,更直接的应用如图 13 所示:(容灾切换)



图 13 RocketMQ on Dledger Multi Center


这里举一个真实的金融应用场景:杭州、深圳和上海分别代表系统中三个节点,进行消息传输。要求:数据一条都不能丢,满足实时高可用并且考虑城市之间的容灾。


Raft 的论文中没有提及如何优先选择某个节点作为 leader,但是我们实现的时候可以自己优化。假设杭州节点服务更好,我们可以指定优先选择杭州节点为 leader。如果杭州节点宕机,可以再把 leader 节点切换到上海,如果上海节点也挂掉,虽然集群不可用了,但是大部分数据还在深圳节点有灾备。深圳主要起复制和灾备的作用,一般情况下不会被选为 leader。


3.4 Dledger 的使用方式

社区 4.4.0 刚刚发表,RocketMQ on DLedger 计划在 4.5.0 发布,目前可以在分支上获取代码:https://github.com/apache/rocketmq/blob/store_with_dledger/docs/cn/dledger/


下载代码之后,可以通过运行社区提供的简单脚本 fast-try.sh 来体验一下。



图 14 RocketMQon Dledger Quick Start


4. RocketMQ 社区发展

4.1 功能点展望

前面主要讲了两个东西:RocketMQ 和 DLedger。DLedger 主要是作为 OpenMessaging 的一个社区在孵化,OpenMessaging 针对消息的存储也抽象出了一套 API,DLedger 是其一个标准的实现。


目前,Github 上的 DLedger 只是实现了 Raft 一些基础功能。后续有很多可以扩展的功能点,比如:


  • Leader 节点优先选择

  • 手动配置 leader

  • 自动降级到 master/slave 架构


4.2 openmessaging-hakv

再看一下跟 DLedger 定位相似的 Java Library:openmessaging-hakv。openmessaging-hakv 结构图如图 15 所示。



图 15 openmessaging-hakv


代码详见:https://github.com/openmessaging/openmessaging-hakv


目前来看,我们没有一个嵌入式且高可用的解决方案。RocksDB 可以直接用,但是它本身不支持高可用。有了 DLedger 之后,我们可以把操作的记录直接写入 DLedger,但是基于这些记录恢复过程我们可以自己选择。假如数据量少,对高可用要求高,比如元数据,我们可以直接存在内存的 hashmap 中,根据 DLedger 的写入记录来构建自己的 hashmap,从而达到数据的一致性和容灾功能。


本文作者:刘振东,GitHub ID dongeforever,阿里巴巴技术专家,2016 年中间件性能挑战赛亚军,具有丰富的分布式系统设计经验,目前负责 RocketMQ 新航道的探索和创新。


2019 年 3 月 04 日 08:0020664

评论

发布
暂无评论
发现更多内容

我摊牌了,大厂面试Linux就这5个问题

艾小仙

Java Linux 面试 大厂

一次产品影响地图的探索之旅

Bruce Talk

敏捷 Agile Product Owner 影响地图

分布式搜索引擎Elasticsearch的架构分析

vivo互联网技术

elasticsearch 分布式 分布式搜索引擎

anyRTC 联合 vInClass 打造在线教育上课模式

anyRTC开发者

音视频 WebRTC 在线教育 RTC

架构探索:事务处理一

李海明

架构师训练营第 1 期 第 11 周作业

李循律

极客大学架构师训练营

区块链防伪溯源平台开发解决方案

t13823115967

区块链+ 区块链产品溯源

JVM垃圾回收?全面详细安排!

程序员的时光

JVM GC

架构师训练营第三周学习总结

Geek_xq

《图解数据结构》.pdf

田维常

数据结构

智慧公安大屏可视化决策系统搭建

t13823115967

智慧公安 智慧大屏可视化

话题讨论 | 用好VSCode这13款插件和8个快捷键,工作效率提升10倍

程序员柠檬

话题讨论

鹅厂大佬亲身经历证明,一周上线百万级并发系统

Java架构师迁哥

研发管理:敏捷研发下周报的价值

云原生实验室

云原生 敏捷 研发管理 周报

话题讨论 | Vue凭什么成为2020的一匹黑马?

黑马腾云

话题讨论

系统稳定性建设实践总结

架构精进之路

系统架构 自我思考 系统稳定性

福利 | 这些网站有免费代理IP!

前嗅大数据

大数据 代理IP 网站反爬 免费代理ip 封ip

蕃茄田宋姝梦:科技赋能时代,儿童在线艺术教育的思考

ZEGO即构

大型团队实践敏捷开发管理的挑战与应对

万事ONES

敏捷开发 研发管理 敏捷开发管理 开发管理

干货分享!用心满满:面试前必知必会的二分查找及其变种

比伯

Java 编程 架构 面试 计算机

美女面试官问我:说说你对序列化的理解

田维常

序列化

深入灵魂的考验,每行注释都是灵魂的单例模式,源码+实例降临

小Q

Java 学习 架构 面试 设计模式

全球熵ETV系统APP开发|全球熵ETV软件开发

开發I852946OIIO

系统开发

为什么阿里人能够快速成长?看完他们Java架构进化笔记,我秒懂!

Java架构追梦

Java 学习 架构 面试 成长笔记

DeFi质押挖矿APP系统开发|DeFi质押挖矿软件开发

开發I852946OIIO

系统开发

智慧公安大数据分析平台开发解决方案,情报研判系统建设

WX13823153201

情报研判系统建设

软件开发中的防呆方法总结

张明云

DevOps 软件开发 技术架构 防呆 模式

K8s 将弃用 Docker;TypeScript 超越 C++ 成第四大语言

京东科技开发者

程序人生

vivo官方商城架构演进之路

vivo互联网技术

中台 架构演进 服务化

苦修月余,斩获bigo、腾讯offer,面经奉上!

艾小仙

Java 腾讯 面试 腾讯大厂

5G多输入多输出技术,到底是个啥东东?

华为云开发者社区

5G 输入 输出

Service Mesh的演化与未来

Service Mesh的演化与未来

阿里数据一致性实践:Dledger 技术在消息领域的探索和应用-InfoQ