速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

阿里数据一致性实践: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:0023600

评论

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

【人民日报】“黄埔星”大模型发布!第三届粤港澳大湾区(黄埔)国际算法算例大赛启动

ModelWhale

人工智能 算法 大模型 竞赛 粤港澳大湾区

PTGui Pro for Mac(全景图拼接制作工具)

Rose

Eclipse、IntelliJ IDEA、PyCharm三种IDE的区别

小魏写代码

电商API接口的大数据分析与挖掘技巧

Noah

初次上手接触ArkTs

华为云开发者联盟

开发 华为云 华为云开发者联盟 ArtTs

Cognizant 与 Microsoft 合作推出了新一代人工智能创新助手

财见

Java Chassis 3技术解密:多种序列化方式支持

华为云PaaS服务小智

Java 华为云

天天crud?试试这个低代码框架

互联网工科生

软件开发 低代码 crud 增删改查 JNPF

用精准分析揭示代币真实价值

Footprint Analytics

区块链 加密货币 代币

macOS高清桌面动态壁纸Dynamic Wallpaper for Mac

Rose

深入理解 Apifox:有效调试 OAuth 2.0 授权接口

Apifox

Apifox 鉴权 OAuth 2.0 Authentication API 安全

让 K8s 更简单!8款你不得不知的 AI 工具

不在线第一只蜗牛

人工智能 AI Kubernetes 人工智能技术

Topaz Video AI视频修复软件 for mac 4.1.0破解版

iMac小白

2023Q3浪潮信息存储装机容量连续11季度稳居全球前三

财见

一次非典型的gitlab镜像库(registry服务)故障排除

大伟

探索Flask接口路由技术:构建灵活可拓展的Python应用

测试人

Python flask 软件测试 自动化测试 测试开发

一文了解密码/国密及应用,密码也卡脖子?

快乐非自愿限量之名

前端 网络安全 信息安全 密码

某客《微信小程序》从基础到实战视频教程

Geek_2e2feb

微信小程序 微信

美国服务器带宽指南:快速、稳定、高效的秘诀

一只扑棱蛾子

美国服务器

JNPF低代码引擎到底是什么?

高端章鱼哥

低代码 JNPF 本地部署

Kurator v0.5.0发布,打造统一的多集群备份与存储体验

EquatorCoco

云计算 k8s 多集群

小程序容器是什么?或许帮你轻松解决移动应用开发难题

Geek_2305a8

免费好用的mkv视频编辑工具:MKVToolNix for Mac

Rose

iText for Mac破解版 OCR图片文字识别翻译 兼容M1/M2

Rose

推荐一个副业,认真做真的很不错

Dominic

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