文档章节

百亿次的锤炼 - 地狱模式的分布式系统测试

n
 nilei
发布于 01/18 18:50
字数 2152
阅读 2246
收藏 37

本文以近期开源的Dragonboat多组Raft库为例,介绍Dragonboat这样一个典型分布式系统是如何做测试的。Dragonboat以Go实现,能在普通硬件上提供每秒1000万次以上的强一致读写,它是目前github.com上速度最快的功能完整的多组Raft开源库。欢迎大家试用,并请点Star支持:Dragonboat

最大的误导

常看到有系统吹捧自己可靠的方法是说某大型活动用了它,或说是某某公司某内部项目用了,从而得出可靠的结论,生产环境俨然成了廉价公关软文口中的测试平台。其实众所周知,某活动全场意外当机重启的节点数少之又少,磁盘毁损一整年才2-4%,而故障性的网络分区在很多DevOps岗的整个职业生涯里也就遇到几次而已,以至于多年来各一线公司网络分区造成故障的故事收集起来也才写满几页纸。某活动扛住了或是某项目用了,这些完全不是软件可靠与否的充要条件。

事实其实是残酷的。曾阅读过国内排名前四的某司一个共识库,30分钟代码读下来找到多处数据丢失毁损的bug,实现则是很典型的那种打死也不肯写测试的全裸奔模式。对于软件,任何无法用代码来验证的廉价营销式说辞,不说、不看、不听:

相较于廉价的文宣,Dragonboat对系统正确性满心敬畏,老老实实以完备的测试方案、开源的测试代码、公开可验证的测试结果数据三者来提供切实的保障。

常规测试

常规测试部分,Dragonboat做了:

Dragonboat内各Package的测试覆盖率基本均在90%以上。以Raft协议实现来看,不正确地删改一行代码基本就能触发多个测试错误。这些测试代码,连同下面要介绍的monkey testing,nightly build时在race detector被打开的情况下运行。对于长期被人诟病的Golang的error处理方式,的确容易因为人为疏忽造成error返回有漏检的可能,但仅gometalinter一个软件收录的静态检测工具就有多种能对付它。对各输入的Fuzz testing初听来或许有些多此一举,但一跑Fuzz testing几十秒就发现bug的例子比比皆是,Dragonboat开发中也曾遇到。

基于Raft协议的自测

Raft协议对内部数据有严格限定要求,比如显而易见的就有:

  • 所有entry的Index值始终应该是连续且严格递增的
  • 所有entry的Term值应该是单向的
  • 当Index与Term确定时,entry内容是唯一确定的

这些都提供较小代价下运行时自测的机会。仅以第一项为例,在Dragonboat中它被落实到多个点位上,对应用透明的进行自测:

  • 在节点完成了协议规定的检查,即将append log时
  • 在entry被commit以后,准备由Raft协议返回供复制状态机执行时
  • 复制状态机即将执行entry,由该entry Index对比当前最新已执行的entry的Index值时

这些自测在Dragonboat中无法通过任何设置予以关闭,甚至在Benchmark跑分时也严格限定必须进行。

磁盘文件IO测试

磁盘文件IO要做正确有多难,可以先看两个事实:

  • Golang的标准库在MacOS上默认的使用,基本必然出现丢数据
  • 专业测试显示,包括git、leveldb、ZooKeeper等最著名项目,丢数据的bug曾有一堆

假设文件系统的可靠是天经地义的吧?很遗憾,这种假设也是高危动作

TS Pillai的这张总结图表直观显示文件IO做正确有多难。

为解决这些磁盘文件IO的挑战,Dragonboat首先选择不自作聪明的到处自己去做文件操作,把存储尽可能交给RocksDB,并对基于RocksDB的系统加以各类测试:

  • 使用ScyllaDB的charybdefs实现的磁盘错误注入测试
  • 使用自动开关的掉电数据完整性测试

前者可以模拟诸如RocksDB试图读一个sst文件的内容时第二次读操作返回错误,帮助检查Dragonboat是否按照设计正确地处理这样的IO错误。掉电测试检查fsync是否被正确配置(如MacOS上是否fcntl(fd, F_FULLFSYNC)了)与调用,是否IO逻辑上有丢数据的问题。

看了上述介绍,可能有人觉得这是小题大做,从Turbo C就开始玩的文件操作有啥难?hehe,文件操作方面是git、ZooKeeper的作者经验多,还是您更牛?

as we know, there are known knowns; there are things we know we know. We also know there are known unknowns; that is to say we know there are some things we do not know. But there are also unknown unknowns—the ones we don't know we don't know.

Donald Rumsfeld

Monkey Testing

Monkey Testing有时也称为Chaos Engineering,目的在于自动测试系统在各组件失效当机情况下系统是否依旧能按设计提供应有的服务。与Fuzz testing的随机数据输入不同,Monkey Testing / Chaos Engineering着眼于随机破坏性事件对系统的影响。

Dragonboat的monkey testing中,各种随机破坏性事件的组合被注入到一个多节点的测试环境里,在一年多的自动测试期间,导致了百亿数量级次数的Raft节点重启事件,发现并修正了大量Raft协议实现与相关辅助功能的bug。整个测试流程及其耗时,堪称地狱模式。具体的,在monkey testing中,被注入的随机事件有:

  • 随意的停止各节点
  • 随意删除节点所有Raft数据
  • 随意丢弃传输中的消息
  • 随意网络分割节点暂时阻断通讯

在上述大量注入的随机破坏性事件前提下,同时在上述多节点测试环境上运行大量Raft组实例,进行Raft的读写测试。该monkey testing环境同时内建一组三个节点的Drummer系统,三个Drummer节点观测、维护各Raft组健康信息,并在发现Raft组的成员失效以后,试图在其它节点上通过Raft组成员变更,新增并启动一个新的Raft成员,替换已失效的Raft成员。

上述三节点的Drummer本身也是一个基于Dragonboat的Raft实现的无单点系统,且在monkey testing中同样会被注入上述随机错误。Drummer的上述监控、修复Raft组的业务逻辑是在自身同样面对大量被注入的随机破坏性事件的前提下完成的,这进一步验证了此类具体实际业务逻辑下,Dragonboat的Raft实现的可靠性。

在一个节点平均存活仅几分钟的情况下,在几台服务器上每晚便可完成千万次量级的节点随机失效与重启测试。在此及其严酷的测试环境中,同时向系统施加Raft读写请求,配合大量后台的Raft快照保存与快照恢复操作,严格的后验检查确保:

  • Jepsen的Knossos和porcupine检查,绝无违反称为linearizability的强一致性
  • Raft组在有Quorum的时候需可用
  • 用户应用状态机状态一致
  • Raft组成员一致
  • 磁盘上保存的Raft Entry Log一致

一部分Jepsen可读格式的edn log已被公布,可供大家使用各自选定的Linearizability checker检验:https://github.com/lni/knossos-data

© 著作权归作者所有

共有 人打赏支持
n
粉丝 11
博文 5
码字总数 9390
作品 1
私信 提问
加载中

评论(2)

v
vritual
打算将这个用在网关授权验证中
山雨欲来
山雨欲来
严谨
警博士SCSDB数据库

最近发现,长期专注于警务大数据分析与应用以及警务实战信息化平台系统建设的专业公司,湖南航天立博信息技术有限公司(合并了湖南航天理想科技有限公 司技术团队)新推出了一种新型数据库系...

上课就好打
2018/01/16
0
0
HBase在腾讯大数据的应用实践

最近正好看到CSDN上一直在宣传腾讯云: 就在不久前,支付宝、携程、蓝翔就因不同原因出现了网络故障,紧随其后艺龙网,途牛网、去哪儿网纷纷遭到大流量DDoS攻击,并造成短暂的业务中断。其中...

dongzhumao
2015/06/12
0
0
lucene的一种新的应用思路(海狗百亿数据的分析)

如何仅用10台左右的机器,在几秒到几十秒的时间内,分析百亿级别的数据? 海狗(Higo)是一个分布式的在线分析查询系统,基于hadoop,lucene,solr,蓝鲸等开源系统作为实现,类SQL的查询语法。...

开心延年
2013/05/03
3K
13
百度运维部校招内推

此次百度运维部校招内推共4个职位,具体信息见下面的链接。 1)北京-运维开发工程师 2)上海-运维开发工程师 3)北京-数据库管理员 4)北京-数据库研发工程师 能在如下城市参加面试的同学优先...

leo108
2013/09/22
2K
6
Apache Kylin 是什么?

Apache Kylin的官网 http://kylin.apache.org/cn/ - 可扩展超快OLAP引擎: Kylin是为减少在Hadoop上百亿规模数据查询延迟而设计 - Hadoop ANSI SQL 接口: Kylin为Hadoop提供标准SQL支持大部分...

技术小哥哥
2017/01/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

php __call,__callStatic

// demo1.php<?phpclass test{public function run(){static::who();test::who();self::who(); $this->who();}public static function __callS...

小张525
6分钟前
0
0
Java发展历史

1995年5月23日,Java语言诞生 1996年1月,第一个JDK-JDK1.0诞生 1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入JAVA技术 1996年9月,约8.3万个网页应用了JAVA技术来制作 1997年...

二九结狐六体
7分钟前
0
0
蚂蚁金服核心技术:百亿特征实时推荐算法揭秘

摘要: 文章提出一整套创新算法与架构,通过对TensorFlow底层的弹性改造,解决了在线学习的弹性特征伸缩和稳定性问题,并以GroupLasso和特征在线频次过滤等自研算法优化了模型稀疏性。在支付...

阿里云官方博客
12分钟前
0
0
Dubbo底层采用Socket进行通信详解

Dubbo底层采用Socket进行通信详解 由于Dubbo底层采用Socket进行通信,自己对通信理理论也不是很清楚,所以顺便把通信的知识也学习一下。 n 通信理论 计算机与外界的信息交换称为通信。基本的...

DemonsI
22分钟前
0
0
Sublime Text3快捷键大全

Sublime Text3快捷键大全 选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本。 Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑。举个栗子:快速选...

linjin200
26分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部