这里主要探讨下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.分布式入库
- 其他参考