在线高并发带索引入库性能优化探讨

这里主要探讨下Nebula在线高并发带索引入库性能优化的方案,希望开发大佬来答疑解惑

  • nebula 版本:v2.0.1

  • 部署方式(分布式 / 单机 / Docker / DBaaS):单机

  • 硬件信息

  • 磁盘( 必须为 SSD ,不支持 HDD)SSD

  • CPU、内存信息:40C 128G

  • 问题的具体描述

物理机单机SSD部署nebula,带索引进行入库速率测试,可以发现写入速率迅速衰减(3w/s->2000/s)。
这里的挑战在于如下,和有限数据关闭compaction全量导入后再统一做compaction(分布式下带索引入库的性能问题 - #3,来自 bright-starry-sky) 或 先导入后rebuild索引(请教带索引情况下提升入库速率的方法 - #2,来自 bright-starry-sky) 不同,这里是在线高并发持续带索引入库,插入也是24小时不间断的,这两种方案都会造成入库速率的抖动,因此这里讨论几种方案

1.调整参数

按照之前讨论(带索引情况下如何提升入库速率 - #4,来自 bright-starry-sky),这里最大的瓶颈在于带索引下插入需要查询旧数据,这种情况下按照文档建议关闭关闭auto_compaction会导致读放大严重,反而制约了写速度,开启auto_compaction可以发现衰减速率迅速好转,配合定时compaction job可以初步满足要求,但是写入速度呈波动状
按照优化读这个思路,增加block cache/开启bloom filter/增加 partition/关闭日志也可以起到一定提升作用,但有个问题这里为什么默认关闭bloom filter,是为了内存考虑吗?

2.修改代码

shermanye这里提到一种解决方案(分布式下带索引入库的性能问题 - #5,来自 shermanye),针对写入全新数据的解决方案。实际上Nebula的INSERT对应NoSQL的UPSERT,以插入点为例,插入一条数据分为如下三种情况

a.插入新数据 1:(name:“www”)
b.插入一条重复数据 1:(name:“www”)
c.插入一条属性修改的重复数据 1:(name:“zzz”)

如果对name建索引,按照现在索引的设计,无论哪种情况都去查询了老数据,而实际上只有case c才需要查询老数据,a/b直接和无索引时一样写入即可,在代码层面屏蔽对旧数据的查询应该可以起到不错提升效果。而实际使用中,在线入库特别是日志场景,很少出现需要修改的问题,所以这里官方这里是如何考虑的,或者说这样修改是否有他风险?

3.优化schema和预处理

这里吴敏提到字段个数的问题(32g内存 16核 使用importer导入只有1w/s ,正常吗 应该调整什么参数呢 - #10,来自 min.wu),这个涉及到另外一个问题,图的schema不能完全照搬关系数据库设计,这里写入属性很多反过来导致compaction压力很大,速度较低,读放大收敛的速度就降低了,反过来制约了写,因此简化属性字段是个提升明显的手段。

另外实际使用中,批量预处理往往比较有用,因为点实体是有限的,批量去重后写入,大大减少写入点数据量,也就减少了compaction压力,提升效果明显。包括一些关系合并和对齐能够提前预处理,不要把这个压力给图数据库,因为它的update并发肯定不会高。

  • 关联问题

1.单机入库

2.分布式入库

  • 其他参考

豁然开朗,感谢博主的分享,研究的很深!

这个问题其实在论坛有不少帖子讨论过,LZ分析的也比较清楚了,我再总结下:

带索引插入主要涉及两步:

  1. 读老的数据,拼出老的索引
  2. 根据第一步的结果,将删除老索引、写新索引、写新数据作为一个原子操作写入

另外有三种情况:

a.插入新数据 1:(name:“www”)
b.插入一条重复数据 1:(name:“www”) (补充一下,对应索引字段的数据不能修改)
c.插入一条属性修改的重复数据 1:(name:“zzz”)

如LZ所说,只有在c情况需要做第一步操作,a/b则不需要。影响性能的也正是第一步,由于是一次随机读,整体实际时read-modify-write的操作,和直接顺序写性能差距很大。(这也是开不开auto_compaction会影响的原因)

对于a/b这个情况,之前给poc用户提供过一个企业版功能,当用户明确知道是a/b情况的时候,可以通过指定一个关键字,跳过第1步。这样性能和正常写入没有问题。

另外,在之前的版本,在同一个part中的多个带索引插入是互斥的(不论是否是写入同一个数据),因此本质上是顺序执行,在raft那一层不能按batch复制,性能会有所影响。

后面在某个版本,其实是做过优化,通过加内存锁的形式,不同数据的带索引插入能够同时进行了,这块性能比之前至少能快1倍。

1 个赞

对于a/b这个情况,之前给poc用户提供过一个企业版功能,当用户明确知道是a/b情况的时候,可以通过指定一个关键字,跳过第1步。这样性能和正常写入没有问题。

感谢大佬解惑,这个后续能考虑放到社区版吗,性能问题真的影响蛮大 :sweat_smile: