nacos-group / r-nacos

Nacos server re-implemented in Rust.
https://r-nacos.github.io/docs/
Apache License 2.0
933 stars 100 forks source link

优化raft集群写入机制,目标提升配置中心写入tps到1万左右 #19

Closed heqingpan closed 8 months ago

heqingpan commented 1 year ago

优化raft集群写入机制,提升配置中心写入tps

主要思路是把raft store查询、写入异步化。 目前是使用同步方式,被io堵塞,tps上不来。目前写入 tps 在2千左右。

【优先级在控制台访问验证开发完成后】

heqingpan commented 10 months ago

【2023-12-24】

开始投入本优化 raft性能工作,梳理优化逻辑。

raft 写入涉及3类数据:

  1. raft log(日志)
  2. raft state machine(状态机)
  3. raft snapshot(快照)

优化原则,最小同步写入原则(其它问题都异步化):

  1. 写入时只同步写入 raft log;初步考虑写入自定义文件中。
  2. raft state machine先写入内存;如果有必要再异步写磁盘。(如果不写入磁盘,启动时需要从 snapshot 和 log构建内存state machine)
  3. 写入snapshot时只用异步写入;初步考虑写入自定义文件中。

详细细节在开发过程中逐步完善,这里不展开。

heqingpan commented 10 months ago

【2023-12-28】

  1. 初步完成 raft log 自定义文件格式,并实现写入、加载器与简单的测试用例;在 mac m1写入每秒tps有9万左右;在旧mac intel i7写入每秒 tps有5万左右;加载raft log耗时小于1ms(只加载索引); 自定义raft log写入性能符合预期,支持异步读写。

因 raft log 只是部分内容暂时不方便与 r-nacos合并,目前是单独建立一个测试工程实现,待raft snapshot 整体验证通过后再逐步迁移替换目前r-nacos中使用的raft 存储。

heqingpan commented 10 months ago

【2024-01-04】

1、初步完成 raft log actor开发,支持加载、写入、支持管理多个raft log 文件,功能自测通过。 2、初步完成 raft snapshot actor开发,支持写入、加载raft snapshot 文件,功能自测通过。 3、初步完成 raft index actor开发,支持管理raft index文件、多个raft log文件、多个 snapshot 文件。

目前新增的raft组件正在整合中,整合完成验证通过后再合并到主干代码。

heqingpan commented 10 months ago

【2024-01-14记录】

单独测试工程中的整体功能基本完成,再通过压测验证tps后,如果没问题再合并到 r-nacos 中。

使用自定义格式文件存储log和 snapshot,整合过程时不时会发现缺少部分内容或者没能异步并行。 整合的工作量感觉不比实现第一版raft工作量少。

heqingpan commented 9 months ago

【2024-01-16记录】

单独测试工程压测结果:

  1. 老 mac cpu i7 + 16G 内存,起3实例集群,单 key 压测,tps在5500左右。
  2. 老台式机CPU:AMD Ryzen7 1700(8核16线程) + 16G 内存,起3实例集群,10万个key随机写入压测, 多次压测tps在9850左右。

施压机器和3个服务实例都在同一台机器,压测时CPU整体使用50%,在机械硬盘和 SSD 压出的结果基本没什么变化。可能有部分处理没有充分并行,使用 actix框架一个actor默认只在一个线程运行,除非做分组或分桶,不然这个并行估计上不去。分组或分桶会增加较大的复杂度,暂不考虑这类进一步优化方案。

测试工程压测结果 tps 9850基本算是达成目标。在性能更好的机器环境tps 应该还有一定的提升空间。

测试工程的raft state machine只是写入内存中,整合到 r-nacos后,部分状态内容需要异步写入本地sled(为了减少改动量,sled维护数据部分本次暂时不动),可能还会消耗部分性能,具体的值要等整合后的压测结果。 预计整合后的tps至少也能在9000以上,也算基本能达成目标。

heqingpan commented 9 months ago

【2024-01-22记录】

非状态机部分代码已完成,后继只要接入 r-nacos现有状态机就算整体完成。

周末测试了不同场景的raft集群场景,目前还有一个(运行一段时间删除部分日志后新节点加入,之后新节点重启有部分日志没有对齐)场景有问题待解决。

周未补充了不同节点的压测结果

台式电脑:

  1. 1个实例: tps: 24673 ; rt 2ms (95%)
  2. 2个实例: tps: 15794, 15428 ; rt 3ms (90%)
  3. 3个实例: tps: 10063,9912 ; rt 6ms (90%)
heqingpan commented 9 months ago

【2024-01-25记录】

初步定位问题原因: 1) async-raft 在打包 snapshot 后需要创建一个Entry::new_snapshot_pointer 覆盖snapshot最后 index对应的日志; 2) 本次优化使用自定义的日志文件内部只支持顺序写入; 上面两点冲突,导致在打包snapshot后新加入的节点与打包前的老节点的日志内容有所差异,导致 commit_index 不能正确更新;而在打包 snapshot 前加入集群的节点没有这个问题。

解决方案:调整自定义日志管理方式,支持再指定 index写入Entry::new_snapshot_pointer覆盖已经打包的日志。

这个调整还需要再花些时间开发测试。

heqingpan commented 9 months ago

【2024-01-31记录】

  1. 完成自定义的日志文件支持覆盖指定 index 用于重写new_snapshot_pointer的功能;
  2. 修复因async-raft members_after_consensus区分空对象与对象列表为空(NoneSome(vec![]))的别区,而实现不区分引发重启后集群不能正常工作的问题。

单独测试工程功能整体测试验证通过,后继工作内容主要是把其与r-nacos状态机整合,然后做对应的压测与功能回归测试。

马上就要过春节,节前能投入的时间不多,节前最多能接入 r-nacos 状态机发个beta版本,本 issue整体开发测试验证通过应该要到节后。

heqingpan commented 8 months ago

【2024-02-20记录】

春节假期已过,继续本 issues开发工作。

调整本次优化 raft性能的变更范围,使用自定义 raft log与 snapshot 后,移除对 sled 的依赖。

最初设计是想只替换 raft log与 raft snapshot,先不动目前的 sled 持久化方式。

但接入状态机过程中发现,如果还用 sled 持久化方式,那么打包 snapshot 镜像时需要多一道从 sled 查询数据的io读操作,这样对最终的性能理论上影响不小;

另外使用 sled 占用的内存比较大,什么不干就多占用20M 左右内存。

索性本次直接把 sled 也去掉,持久化只用 raft snapshot 加 raft log 储存,启动时加载 snapshot 与 log即可把数据恢复到内存中,这样性能更高。

这样调整后工作量比原计划会多一些,评估后还算在可控范围。另一方面调整后的版本与目前的正式版本数据不直接兼容,升级版本需要做数据迁移,后面考虑是不是需要提供工具做版本升级数据迁移(也可以先通过管理后台的导入、导出配置做数据迁移)。

  1. 初步完成新raft filestore 接入配置中心状态机。
heqingpan commented 8 months ago

【2024-02-28记录】

  1. 初步完成r-nacos接入raft file store替换原sled raft store,并已能成功启动运行; 2.切换file store后,r-nacos 整体功能初步验证通过;后面再补充性能压测验证。
heqingpan commented 8 months ago

【2024-03-03记录】

对调整后的代码进行压测,不同节点数量的集群(在本人的单台台式电脑)压测结果如下:

1个实例: tps: 17625 ; rt: 6ms (90%) 7ms(95%) 2个实例: tps: 13998; rt: 7ms (90%) 8ms(95%) 3个实例: tps: 7635 ; rt: 14ms (90%) 15ms(95%)


两个实例以下 tps 能稳定大于1万,3个实例时tps 在7500左右。

raft 集群主要受到网络 io 与磁盘 io 的影响。

在同一台机器部署集群,网络io损耗最小,但多个实例共用一个磁盘 io,磁盘影响较大。

如果换成网络带宽允足的多个机器部署集群,磁盘 io 能提升,网络损耗不是很多,那么集群的 tps 应该还能提升。

上面的压测结果,算是勉强达到预期。

后面做好全面的功能回归验证与收尾工作后,再发布新版本。新版本存储与0.4x不兼容,新版本号应该是0.5.x 。

boringhello commented 8 months ago

hello, 你好。请问下你的这个压测是在同一台机器上的集群吗,客户端开了多少并发线程测的呢,读写是随机的吗,以及平均latency是多少,机器配置如何?能详细描述一下你单机集群压测程序的设置吗

heqingpan commented 8 months ago

hello, 你好。请问下你的这个压测是在同一台机器上的集群吗,客户端开了多少并发线程测的呢,读写是随机的吗,以及平均latency是多少,机器配置如何?能详细描述一下你单机集群压测程序的设置吗

我上面的记录有两类,最上面的是纯 kv db的测试服务,后面是改造后的 r-nacos 配置中心。你应该是指改造后的 r-nacos 配置中心吧。

我按r-nacos 配置中心压测来说明:

如果想验证可以按上面的步骤做压测,在 raft_opt 分支我加了一个http_config_set2 1w个随机key的压测,有兴趣也可以试试。我这边单实例压1w个随机key tps 大概15200 左右。

有自行压测结果也欢迎在本 issue 分享下。

heqingpan commented 8 months ago

【2024-03-10记录】

这项优化的变更已初步完成测试验证,以发布到v0.5.0-beta 版本。

观察几天没有问题后,再发正式版。