在我最开始学习编程的时候,我一直觉得写程序是很简单的事情,程序总是按照我的想法串行的执行,给一个输入,总是有着符合预期的固定输出。那时候写代码,可能大的挑战在于理解分支,循环,但无论怎样,只要控制得当,事情总是确定的。
那段时间可以算是非常快乐的日子,直到我遇到了多线程,人生中第一次有了『自信被打破』的恐慌,在多线程的世界里,事情不会在按照我想的方式来正常的运转,我需要考虑 data racing,需要考虑 memory ordering。幸运的是,在经历了短暂的不适应之后,很快我就能很好的拥抱并发了,毕竟我们这个世界本来就是在并行运转的。虽然写多线程程序相比之前更加的困难,但其实只要掌握了一些多线程的并发原语,知道如何使用 mutex,semaphore,channel 这些,其实会发现多线程的世界也是蛮有意思的。再加上,新一代的编程语言,无论是 Go,还是 Rust,都能让大家更加游刃有余的处理并发问题,只要处理得当,给定一个输入,仍然能得到我们想要的输出。只不过,这时候要保证确定性要比之前困难了很多。
但好景不长,在驾驭了多线程之后,我的『自信再一次被打破』了,因为我进入了分布式系统的世界,在这个世界里面,一切都变得不再确定。给定一个输入,我可能得到的结果是未知,因为我不知道这个执行在远端是否被正常的执行了。而人类对于未知恰恰是最恐慌的。我不知道我的系统什么时候会出现网络异常,或者磁盘什么时候突然坏掉,或者机房是不是突然断掉了,一切的一切,对我来说都是未知的,譬如下面是我们在实际中遇到的一个问题:
我们的用户将 TiDB 运行在国内某云厂商的机器上面,然后跟我们反映,读延迟会不定期的增长,我们看了看监控,发现唯一的异常指标就是 Cached 的 memory 那段时间会突然下降。当时真的就懵了,完全不知道原因是什么。最终发现,云厂商的运维监控脚本里面有个 bug,会不定期的将磁盘热拔插,并且将现有的 page cache 刷到磁盘,所以那段时间 TiDB 的 read 操作很多是从磁盘重新读取数据的。
可以看到,分布式系统真的是一个非常复杂的系统,故障无处不在,那么我们如何在这么复杂的分布式系统的世界里面生存下去呢?现在,一个很好的答案就是 - Chaos Engineering,中文里面叫做混沌工程。
相比于我们成天担惊受怕系统会出现什么样的问题,还不如提前就模拟线上环境可能出现的各种情况,来看我们的系统是否能做到容错,仍然能继续对外提供服务。当然,我们并不是简单的就在线上环境上面,把机器给断电,或者把网线给拔掉,在混沌工程领域,有一套指导原则,以及标准的实验步骤,具体的可以参考 PRINCIPLES OF CHAOS ENGINEERING 。
简单来说,要做一次混沌实验,我们只需要做到如下的 4 个步骤:
可以看到,上面的步骤非常的简单,但要在实际中很好的做混沌试验,还是有一些困难的,主要在以下几点:
所以,为了让大家更好的做混沌试验,我们开发了 Chaos Mesh®,Chaos Mesh® 是一套基于 Kubernetes 的云原生混沌工程平台。Chaos Mesh® 的架构如下:
相比于其他混沌平台,Chaos Mesh® 有如下优势:
在我们开始一次 Chaos 实验之前,你首先需要满足两个条件:
另外,在开始实验之前,这里我还是要强调一下 Chaos 实验的一些注意事项,可能你觉得我这个大叔很啰嗦,但小心驶得万年船,因为稍微一不注意,你可能就丢了数据了。
好了,现在你已经完全准备好了,现在就可以踏上混沌之旅了,因为 Chaos Mesh® 的使用是如此简单,你只需要参考 用户指南 就能上手使用,所以我就不过多介绍了,如果你仍然遇到了问题,欢迎给 Chaos Mesh® 提 issue,相信我,Chaos Mesh® 社区会很热情的帮你解决问题的。
随着 ServiceMesh,Serverless 等理念的兴起,我们的系统真的越来越趋向于分布式,这样虽然简化了我们单个模块的实现,但整体来看,也可能会导致我们的系统因为过于分布式而变得复杂,那么如何在这种复杂的环境下仍然让我们有信心能保证系统的正常稳定运行,混沌工程可以算是一个很不错的选择。
现在市面上面,支持混沌工程的平台已经有很多了,但我这里仍然推荐 Chaos Mesh®,毕竟使用它能让你极大提升你对系统的信心。
最后,欢迎来到复杂的分布式系统世界。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。