科普365

科普365

百度正式开源其Raft一致性算法实现braft

发布时间:2018-03-11 20:51:02 来源:搜狐科技 责任编辑:admin

作者|王耀

编辑|徐川、郭蕾

2017 年 9 月 14 日,百度正式在 GitHub 上基于 Apache 2.0 协议开源了其 RPC 框架 brpc。brpc 是一个基于 protobuf 接口的 RPC 框架,在百度内部称为“baidu-rpc”,它囊括了百度内部所有 RPC 协议,并支持多种第三方协议,从当时的性能测试数据来看,brpc 的性能领跑于其他同类 RPC 产品。

InfoQ 也曾对这一事件做了重点报道,到现在,brpc 已经有超过 6000 个关注,17 个代码贡献者,看来社区对这一开源项目还是极为关注,知乎上一个 ID 为彭哲夫的用户对 brpc 评价极高,他说:

BAT 开源这么「多」项目里面,brpc 应该是我见过最好的之一。光是这篇文档里面所记录工程问题的解决方法,落地解决方案什么的已经可以吊打每年 2 次某大型码农交友会里面的各色分享,干货十足。

看文档就能学到不少工程领域用于处理特定稳定的不少手法,至于 CPP 其实不重要,语言只是工具。rpc 这个东西在工程领域说实话很容易被忽视,性能,接口,易用性什么的其实都需要权衡。而一般人只会看重性能这个说实话不算优先级最高的东西,当然不是说性能不重要啊,性能也要分场景的。

这个 brpc 关于测试那一部分写得太好了,抛开场景和业务逻辑用 echo helloworld 谈 QPS 就是耍流氓。同样的异步同步之争在豆瓣也探讨过,不是说异步就是银弹,同步就是药丸,也是要结合业务场景来选择的。这一些工程上小细节都写得挺不错的,就算用不上这个项目,也可以多读读其文档。

而在 2018 年 2 月初,brpc 团队又开源了其基于 brpc 的 Raft 一致性算法和可复制状态机的工业级 C++ 实现 braft。这个项目最初是为了解决百度各业务线上的状态服务单点隐患,后来则帮助百度工程师独立实现支持高负载和低延迟的分布式系统。项目地址如下:

https://github.com/brpc/braft

当前 braft 在百度内部大概有十几个应用场景,部署了 3000+ 服务器,有做 Master 模块 HA 的,也有用作存储节点复制修复的。其中百度云的块存储、NewSQL 存储以及即将推出的 NAS 存储、强一致性 MYSQL 都是原生基于 braft 构建的。为了了解更多关于 braft 的信息,InfoQ 记者采访了百度云架构师、braft 项目负责人王耀。

王耀目前担任百度云 IaaS 方向技术负责人。2010 年加入百度,一直从事基础架构相关工作,先后领导了百度分布式消息队列 bigpipe、分布式文件系统 NFS 和 AFS、分布式块存储 CDS 的设计开发工作,历经百度分布式存储系统发展的各个阶段。最近聚焦在网络虚拟化方向,专注 SDN 控制器和 DPDK 高性能转发网关。

同时,王耀也是 QCon 北京 2018 的讲师,他将会在会上分享《Raft 在百度云中的实践》相关内容,感兴趣的读者还请关注(会议时间是 4 月 20 日)。

InfoQ:请介绍一下 braft,它的主要特性有哪些?

王耀:braft 是基于 brpc 的 Raft 协议工业级 C++ 实现,设计之初就考虑高性能和低延迟。由百度云分布式存储团队打造,在百度内部已经有比较广泛的应用,比如一些关键模块的高可用,以及分布式块存储、分布式文件系统、分布式 NewSQL 系统、分布式文件系统等存储系统。它有如下特点:

InfoQ:可否详细介绍一下 braft 的开发历程?

王耀:在构建分布式存储系统过程中,一般会有 Master 来实现一些节点加入离开、副本修复、负载均衡以及业务相关的元信息 CURD。对于这些 Master 模块的 HA 我们做过很多尝试,比如 keepalived、QJM 等,一直没有比较理想的解决方案。

在 2015 年中的时候,我们想到用 Raft 来解决这个问题,Raft 的复制状态机能够解决高可用的问题,选主和节点变更也非常方便,不用再依赖 ZK。

到 2015 年 11 月份,我们完成了 braft 的第一个版本的开发,用 clojure 搞了一个 jepsen 的测试 case,验证没有问题。

在 2016 年的 Q1 末我们开始使用 braft 构建新的分布式块存储,整个开发过程相比之前的存储系统要快很多,投入了 4 个半人力不到 2 个季度就完成了第一版开发,后续就是不断的迭代测试不断的打磨。这中间对 braft 的接口和协议做了一些改动,比如支持了 prevote、leader transfer,丰富一些回调和 stats 统计等等。

新的块存储系统在 2016 年底开始逐步小流量,并在 17 年中开始了漫长的新老系统数据迁移工作,当前百度云磁盘底层大部分已经是由新系统来承担了。在块存储测试上线的过程中,逐渐有一些其他的系统开始使用 braft,比如我们的 NewSQL 系统 TafDB、强一致数据库,以及一些业务关键模块 HA 等等。

InfoQ:braft 上线运行的情况如何?在线上是否踩过坑?

王耀:当前 braft 在百度内部大概有十几个应用场景,部署了 3000+ 服务器,有做 Master 模块 HA 的,也有用作存储节点复制修复的。其中百度云的块存储、NewSQL 存储以及即将推出的 NAS 存储、强一致性 MYSQL 都是原生基于 braft 构建的。除了传统的分布式存储还有一些偏业务的应用场景,比如百度地图开放平台用 rocksdb 和 braft 构建了一套轨迹服务系统,提供高可用的轨迹存储和计算服务。

braft 库本身踩的坑倒不多,更多的是库的使用过程中踩的坑:

  1. on_snapshot_load 的时候没有清空状态机导致状态数据错乱
  2. on_apply 的时候因为一些随机算法或者是因素导致主从执行结果不一致
  3. apply 的时候卡住了,切从又切成主,这个过程中这条数据被其他节点成功 apply 了,就会导致 log 被正常的执行了两遍
  4. on_leader_stop 的时候 leader 上的一些任务没有 cancel 掉导致 job 的下游节点出错;

这里面说明一下 braft 的测试情况,主要分为三部分:test 目录下面的 unit test;jepsen 目录下的 atomic example 的 jepsen 测试;分布式存储业务系统的压力和异常测试集群,在上百台服务器上注入类似 jepsen 的进程 kill/stop、网络划分、节点间单通、文件系统读写出错等异常。

InfoQ:braft 和 brpc 的关系是什么,两者是否绑定?

王耀:首先明确一下两者的目标:braft 是解决复制状态机问题,brpc 是解决模块间 RPC 通信问题。braft 中 Raft 协议的互通直接使用 brpc 实现,runtime 使用了 bthread,因此 braft 编译需要依赖 brpc,从这点来看 braft 和 brpc 有一定的绑定关系。

但是从另一个角度来看,braft 中核心的是协议状态机比如 log、snapshot、configuration 这些东西的抽象和实现,协议 RPC 只是其中一环,做一层 transport 抽象也可以比较容易的替换为其他的 coroutine based protobuf RPC 框架,对于非 coroutine based protobuf RPC 来讲,braft 只能用类似 logcabin 中 pthread 同步 RPC,这样就丧失了多复制组支持的特性,RPC 的回调改造成本就比较高了。

InfoQ:Raft 是否会成为分布式一致性算法的主流,是否还有提升空间?

王耀:当前来看 Raft 已经成为分布式一致性算法的主流,业界的 TiDB、CockroachDB、etcd、consul 等一系列流行的组件和服务都在使用,但是业界还有一些其他的 paxos 变种比如 epaxos,未来可能会有一种新的 Paxos 变种成为主流。

对于 Raft 来讲基于日志的连续提交的设定,相比 multi-paxos 的乱序提交在写入性能上会有些差距。对于 Raft 协议来讲没有太多改进空间了,但是对 braft 要做一个理想的 Raft 库实现的话,依然需要不断的改进和优化。

InfoQ:您从事基础架构研究工作多年,能否对从业人员分享一些经验?

王耀:做基础架构工作,第一要做的是时刻关注学术界和企业界的发展,多与同行交流来获取业界的发展动态,不断的提高自己的眼界,有助于做出更好的系统设计。

在大型系统设计的时候需要能够构建清晰的模型,模块怎么划分怎么交互。模型清晰之后就是系统的详细设计,分布式系统中有很多时序相关的东西和问题,不能像单机一样去调试,所以在设计阶段就要把系统中的每个细节都想清楚,能够推演系统的各个流程。思考系统中各种race condition,对于这些race condition要量力而行,避免过早设计过早优化导致项目延期;解决方案尽量简单,避免方案实现引入新的问题。

架构改进要数据说话,通过各种工具和日志等分析出系统架构中 top 的三个问题,然后针对这些问题制定相应的改造方案。这里需要注意的是方案设计不仅仅是提出一个全新的解决方案,还需要考虑如何把系统从当前方案迁移到新的方案,同时确保迁移过程是尽可能的平滑无损。

对于重大版本在开发测试完成之后,需要做几次上线演练,记录并修正演练过程中的非预期问题。这样经过几次迭代之后,系统的问题就会逐步收敛,当收敛到一定阶段之后,如果依然有一些比较大的问题难以修复,这个时候根据人力条件判断是继续在现有条件下规避问题,还是整体重构或者是部分重构来解决问题。

想跟《Java 编程思想》的作者当面交流?

QCon 北京 2018 将于 4 月 20~22 日举行,目前已经邀请到《Java 编程思想》的作者 Bruce Eckel,《卓有成效的程序员》和《函数式编程思维》等畅销书的作者 Neal Ford,Apache Kafka 主要作者、项目委员会主席(PMC chair)Jun Rao,百度贴吧之父、滴滴产品高级副总裁俞军,Oracle Java 平台事业群 VP Georges Saab,还有 VR 领域的大牛,南澳大利亚大学教授、2013 IEEE VR 技术成就奖得主 Mark Billinghurst,另外 Prometheus 监控系统创始人之一 Julius Volz 也会分享 Prometheus 架构设计与最佳实践。Kotlin 核心开发团队的专家也会到场。