[关闭]
@pockry 2018-03-06T11:52:43.000000Z 字数 3251 阅读 7413

百度开源braft:工业级高性能Raft库

云计算


前段时间,百度发布开源RPC服务框架brpc,逐渐将自己在分布式计算方面的技术沉淀下来,并回馈开源社区。

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

我们对项目的技术负责人王耀进行采访,了解了更多细节。王耀也将在4月21日QCon北京站上分享演讲,敬请关注。

受访嘉宾介绍:

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

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

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

  • braft是一个功能完备且经过可靠性验证的Raft实现,支持configuration change、prevote、leader transfer等特性;
  • 高性能也是braft追求的核心目标,在实现的很多环节都进行了精细优化,比如无锁任务队列、log的批量提交和执行以及一些逻辑原地执行等;
  • 接口简单容易理解,支持自定义扩展其中的storage,拥有比较完善的错误回调。

braft配合brpc可以利用其复制状态机快速搭建各类分布式系统。

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库本身踩的坑倒不多,更多的是库的使用过程中踩的坑:

a) on_snapshot_load的时候没有清空状态机导致状态数据错乱

b) on_apply的时候因为一些随机算法或者是因素导致主从执行结果不一致

c) apply的时候卡住了,切从又切成主,这个过程中这条数据被其他节点成功apply了,就会导致log被正常的执行了两遍

d) 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的三个问题,然后针对这些问题制定相应的改造方案。这里需要注意的是方案设计不仅仅是提出一个全新的解决方案,还需要考虑如何把系统从当前方案迁移到新的方案,同时确保迁移过程是尽可能的平滑无损。

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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注