Open rpbear88 opened 3 years ago
这个方案的前提依然是,我们认为braft的实现原理上没有特别多的导致性能差的点(虽然实验数据看起来并不是这样,我们还在进行调整),依然认为最大的性能问题来自于raft算法本身。
而对braft来说,leader上本地日志提交和两个peer的replicator对log entry队列的争抢虽然有一些锁的保护,但是锁竞争并不会很大(和peer数相等)。
Raft的串行化阶段对这种超低延时的存储系统不够友好。这个改造方案里最复杂的其实是配置变更
@rpbear88 你们遇到的问题和阿里 polardb 团队很类似, shard-stoage 的数据库复制的时候需要 raft 乱序提交 + 乱序执行来降低延迟, 他们提出了parallel raft 算法, 但是我看了论文对比了一下 multi-paxos, 这个对 raft 改造很大... 所以你们可以考虑不基于共识的方案, 简单来说就是放弃 raft...
各位好,
我们正在使用braft构建我们自建的存储系统,我们做了一个原型系统来验证braft的性能,原型系统的一些要点如下:
MemoryLogStorage
,想忽略这块在磁盘IO上的消耗,因为目前基于文件系统实现的LogStorage的延迟较高,针对一个8K的日志提交延迟会超过300us,远差于基于SPDK实现的IO性能因此,整个服务端处理写IO的流程是这样的:
on_apply
,此时会将raft同步完成的请求提交给存储引擎(通过SPDK的ring队列),此处会产生worker thread和引擎thread间的数据交换目前在单队列的4K写场景下,braft从得到任务到调用on_apply耗时约90us(这个结果显然不能满足实现低于100us的IO延迟的存储系统的要求),我们还在调查这个延迟具体消耗在什么位置。但是考虑到raft本身的一些weakness,我们想从原理上看看是否有更好的方案,下面是我们提出的一个方案(感谢@PFZheng提供的思路)。
元数据和数据使用不同的复制方式
普通的主从同步方式,从并发的角度来说性能是优于raft的,因为它没有顺序提交的问题,但是主从方式做replication的缺点在于:
从数据同步的角度来说,raft和主从协议性能损耗可以认为是一样的,在raft中leader的日志只要确定了log id,是可以并行发给follower的。但是在日志持久化阶段,raft日志必须是串行提交进日志系统,这是其一个缺陷。在apply阶段,从实现层面来说,不冲突的请求可以并行apply,但是目前实现一般都是顺序apply,因为会依此更新apply idx,所以apply的顺序不能乱。所以这里的一个解决思路可能并不是去并行apply,这样在既有的raft框架内改动也较大,而是尝试让apply尽可能快,那么这个顺序apply的开销就会很小,比如像redis那样纯内存的操作,那么性能也是可以做到非常强悍的。
由于我们的存储引擎对数据的修改采用的是非原地写(out-of-place write),我们考虑整个流程处理成如下步骤:
我们的改造主要有两个方面,第3步的改造,相当于让原本顺序执行的提交日志项变成了并行提交,理论上对性能提升有帮助。而apply阶段则变成纯内存操作,不涉及IO。
从原理上来说,我觉得raft的方案是有一个悲观锁的解决方式,用串行化来解决可能存在的争端但是在冲突不大的情况下性能不行。而结合主从复制的模式,相当于是一个乐观锁的解决方案。
很想听听大家对这个问题的解决方案的看法。