0%

01 Basic Raft协议

本文目标:分享笔者自己对Basic Raft的流程和设计目的。为了降低复杂度,本次不涉及任何性能优化成员变更,只关注正确性(也称safety)

引言

多副本机制是提高系统容灾能力的手段之一。使用多副本机制引入一个新的问题——如何让不同副本的数据保持一样。客观上,副本之间有快有慢,数据会存在不一样的时刻(苛求数据同时写入所有副本本身就是不可能的)。通过共识协议解决副本之间的数据一致性问题:我们可以通过共识算法对用户屏蔽副本之间的差异,最理想的情况就是用户使用起来和单副本没区别,感知不到副本的存在。

不少项目如etcd、TiDB等均采用Raft作为他们的共识协议。本文基于Ongaro的博士论文中的第三章,首先介绍basic Raft(后文均简称Raft)的流程;然后结合笔者自己的理解,讨论协议的设计思路;最后简单讨论协议的正确性。

阅读全文 »

分布式协议很难证明其正确性,常规想法是通过测试尽可能覆盖所有可能。但实现是,再多的测试也很难覆盖住所有的可能,如果在线上暴露问题,会造成严重的后果。形式化验证正是为了解决这样的问题,它使用计算机强大的计算能力,暴力的搜索所有可能的行为,检查是否满足事先设定的属性,任何不符合预期的行为都能被发现,从根本上保证算法的正确性。

一句话说,在理论上通过暴力搜索所有的可能保证协议理论的正确性,之后只需要考虑如何正确的实现协议。在出问题时不需要考虑协议是否有问题,而是代码实现的有问题。

TLA is a language for high-level modeling of digital systems. High-level means: at the design level; above the code level.

can help find and correct design errors: errors hard to find by testing; before writing any code

阅读全文 »

研究生期间,利用学校的云服务器搭建了一个k8s集群,使用rancher来做管理软件。我们使用rancher来作为我们的测试发布平台,相比于原始的docker,这种模式更简单快捷。但是面临一些问题,比如缺少一个好的日志工具,来收集和统一查看(短暂的搭建过ELF,但是没有使用起来);

其次缺少一个存储平台,比如集群一共有16台服务器,我要启动若干个服务测试,服务的调度交由k8s调度,每个服务有着自己的配置文件。发现问题了吧,服务可能会出现在16台服务器中的任意一台上,所以需要拷贝16份副本放在素有服务器的相同位置。开始我们搭建了一套NFS,但是随着测试规模越来越大,NFS的写入成为了测试系统的瓶颈点(后文会具体提到原因)。所以后来采抛弃了这个方案,选择在在部署时候,把同一份文件拷贝到所有服务器上,这样的代价就是一次部署测试的时间会很长。

现在也没有更好的解决方案,选择还是回退到NFS,但和原来的稍有不同,等有时间在详细写写

阅读全文 »

(这是笔者在美团实习时做的一次源码分享,当时直接将本文当作slide,所以很多地方写得比较简略)
本文以Kafka 0.10.0为例,追踪broker端通用请求处理链路。本文侧重一个请求在Kafka的组件中如何流转,不会涉及太多网络层(Java NIO)和请求具体的处理实现。

阅读全文 »