阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

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

评论

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

腾讯阿里工程师所热衷的DPDK到底是个什么东西?该如何学习?

Linux服务器开发

Linux服务器开发 DPDK C++后台开发 Linux后台开发 虚拟化技术

万字长文:直击关于Docker所必须了解的知识

穿过生命散发芬芳

Docker 4月月更

[Day14]-[动态规划]四键盘问题

方勇(gopher)

LeetCode 数据结构与算法、

如何在Unity中免费制作游戏

龙智—DevSecOps解决方案

Unity Perforce Helix Core

企业如何进行信息化

秋去冬来春未远

数字化 信息化管理 如何信息化 信息化规律

大厂工程师所热衷的DPDK到底是个什么东西?

赖猫

Linux 网络协议栈 DPDK

读《Software Engineering at Google》(03)

术子米德

架构师成长笔记

一文带你搭建RocketMQ源码调试环境

悟空聊架构

RocketMQ 4月日更 悟空聊架构 4月月更

jupyter notebook换皮肤

Peter

Python 机器学习 数据分析 Jupyter Notebook

Docker容器简介、优缺点与安装

乌龟哥哥

4月月更

在线IEEE浮点二进制计算器工具

入门小站

工具

ThreadLocal理解及使用

Rubble

4月日更 4月月更

“双碳”强风吹拂:数据中心的绿色改革图谱

脑极体

基于卷积神经网络的猫狗识别

Peter

机器学习 深度学习 tensorflow keras

Python 报错 ValueError list.remove(x) x not in list 解决办法

AlwaysBeta

Python 编程

GraphScope v0.12.0 版本发布

6979阿强

大数据 图计算 GraphScope 图分析 图数据

半导体行业如何保持高效远程办公?因果集群(Causal Clustering)了解一下!

龙智—DevSecOps解决方案

远程办公 因果集群

seaborn绘制箱型图

Peter

可视化 数据可视化 seaborn

Flutter 2.0的路由把我搞蒙了!!!

岛上码农

flutter 路由 移动端开发 4月月更 跨平台开发

自己动手写Docker系列 -- 5.7实现通过容器制作镜像

Go Docker 4月月更

linux之chroot命令

入门小站

Linux

在 K8s 上运行 GraphScope

6979阿强

大数据 图计算 GraphScope 图分析 图数据

使用 Helm 部署 GraphScope

6979阿强

大数据 图计算 GraphScope 图分析 图数据

图计算 101:图计算的类型、语言与系统

6979阿强

大数据 图计算 GraphScope 图分析 图数据

读《Software Engineering at Google》(04)

术子米德

架构师成长笔记

TypeScript基础学习

乌龟哥哥

4月月更

通过质量内建,提高交付质量

老张

软件测试 质量内建 交付质量

在线CSV转Excel工具

入门小站

工具

从安装到编译: 10分钟教你在本地使用和开发GraphScope

6979阿强

大数据 图计算 GraphScope 图分析 图数据

用 GraphScope 像 NetworkX 一样做图分析

6979阿强

大数据 图计算 GraphScope 图分析 图数据

基于机器学习算法的钢材缺陷检测分类

Peter

Python 决策树 随机森林 集成学习 LightGBM

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