红帽白皮书新鲜出炉!点击获取,让你的云战略更胜一筹! 了解详情
写点什么

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

作者:刘振东

  • 2019-03-04
  • 本文字数:4268 字

    阅读完需:约 14 分钟

阿里数据一致性实践: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-03-04 08:0023062

评论

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

一图解析MySQL执行查询全流程

华为云开发者联盟

MySQL 服务器 数据包 查询语句 应用层

【直播预告】全国人工智能大赛赛题讲解直播来啦!1月6日晚20点,不见不散!

OpenI启智社区

人工智能大赛

Java开发之SSM框架整合配置知识分享

@零度

ssm JAVA开发

网络安全好学吗?手把手教你学metasploit 网络安全工程师学习资料汇总

学神来啦

React 中五种常见的使用样式

编程江湖

React

HBase 优化如何操作

编程江湖

HBase

使用APICloud开发app的性能提升实践

YonBuilder低代码开发平台

android APP开发 APICloud 跨端开发 app性能

安装VTK配置出现错误

Ayosh

qt

前端培训:React Native 开发过程中遇到的坑

@零度

前端开发 ​React Native

docker

Docker jenkins pipeline

百度飞桨EasyDL桌面版正式上线,没网也能训练AI!

百度大脑

人工智能

惟客数据“惟客云”升级:稳操胜“券”,助力商家精准营销

科技热闻

阿里巴巴集团副总裁贾扬清-一个AI开发者的奇幻漂流

大咖说

Dumpling 导出表内并发优化丨TiDB 工具分享

PingCAP

大数据培训:hadoop中shuffle过程面试题

@零度

大数据 hadoop Shuffle

云计算厂商们,你们辜负了中国的用户

码农一米

云计算 云服务

Linux之目录结构

入门小站

「offer来了」面试中必考的15个html知识点

星期一研究室

html html5 css3 前端 html/css

如何解决JDBC死链接导致NIFI线程假死

编程江湖

自创解法!setTimeout+Promise+Async输出顺序?简单的一匹!!

Sunshine_Lin

面试 前端 ES6 Promise Async

VRAR产业峰会暨第二届华为VR开发应用大赛颁奖典礼在和平区成功举办!

华为云开发者联盟

云计算 5G AR 华为云 vr

Greenplum 内核源码分析 - 分布式事务 (五)

王凤刚(ginobiliwang)

源码分析 greenplum 分布式式事务

绥北人民法院:用宜搭打造“线上法庭”,让群众少跑腿

一只大光圈

低代码 数字化转型 法院 钉钉宜搭

微信小程序获取位置信息

程思扬

小程序 小程序云开发 开发者 开发 小程序生态

【MongoDB学习笔记】MongoDB索引那点事

恒生LIGHT云社区

数据库 mongodb 索引

2021年度总结,欲望反光

程思扬

经验分享 #总结# 经验总结 盘点 2021

Stellantis集团将于2022CES展期间召开网络直播发布会

InfoQ_967a83c6d0d7

“千言”开源数据集项目全面升级:数据驱动AI技术进步

百度大脑

人工智能

基于机器学习和TFIDF的情感分类算法,详解自然语言处理

华为云开发者联盟

自然语言处理 机器学习 算法 TFIDF 情感分类

甲方,你们愿意被乙方侮辱吗?

码农一米

云计算 云服务

带你认识传统语音识别技术

华为云开发者联盟

语音识别 语言模型 声学模型 隐马尔可夫链 WFST解码

阿里数据一致性实践:Dledger 技术在消息领域的探索和应用_大数据_InfoQ精选文章