关于nebula graph的几个疑问

大家好,我现在在进行图数据库选型前期分析,在分析nebula graph的相关资料时有一些疑问,请大家帮我解解惑:

1、关于后端存储设备,文档中多次强调推荐后端使用SSD,比如:

Nebula Graph是针对NVMe SSD进行设计和实现的,所有默认参数都是基于SSD设备进行调优。
不推荐使用HDD,因为HDD的IOPS性能差,随机寻道延迟高,可能还会遇到许多其他问题。

请问如果使用HDD的话,有功能上的问题吗?还是只是性能上弱一些,但是功能正确性还是有保证的?有针对HDD进行一些测试吗?由于一些原因,我们身边当前都是HDD的硬盘。

2、请问nebula graph的数据写入过程是什么样的?有哪些常规方法用来提高(并发)写入速度?
文档中介绍后端一个图分为多个partition,partition多副本采用raft协议进行。请问写某个partition时是并发写吗?还是会加个partition锁串行写?如果partition是串行写,那么即使graph服务是并发的,底层会不会成为写入瓶颈?如果partition是并行写,会加节点锁吗?单个节点的读-修改-写操作是不是原子的?

3、请问nebula graph的数据读取过程是什么样的?
读取数据时,会在leader和follower partion间做负载均衡吗?还是只会从leader partition进行数据查找?

4、关于带索引写的性能问题
在文档中多个地方强调:

MATCH和LOOKUP语句的执行都依赖索引,但是索引会导致写性能大幅降低(降低90%甚至更多)。请不要随意在生产环境中使用索引,除非您很清楚使用索引对业务的影响。

论坛中也有很多讨论这个问题的帖子。

我的应用场景是在线从kafka读取数据,然后建立图模型写入图数据库中,期间会有大量对已有节点或边的修改操作,由于查询的场景,我们也会建立较多的索引。

请问对于我的这个应用场景,有哪些可以提高写入性能方法的建议?在线带索引写入场景的性能优化我们有相关的改进计划吗?

5、match和lookup的区别和使用场景分别是什么?
有了match查询语句为什么还需要lookup查询语句?他们的区别和使用场景分别是什么?

6、关于全文检索
文档中介绍,native索引是不支持前缀查找、模糊查找等非精确查找类型,这些需求需要通过elasticsearch实现,且elasticsearch索引当前是异步实现的。请问加了elasticsearch后,对写入性能影响大吗?

7、vid的选择问题
vid可以是int64,也可是fix_string,请问这两种方式在读写上面哪个更有优势?系统推荐优先选择那种?(fix string具有实际的业务语义,int64并不对应业务语义,只是唯一表示节点的id)

1 个赞

美团赵老师的视频 可以看看 nLive vol.001|美团图数据库平台建设及业务实践_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

那你得慢慢调参数吧,对应的HDD参数很难调出来,调不出来就基本不能正常运行

你的意思是基本上不要考虑使用HDD硬盘吗?盼回复。文档里似乎说明需要调一些超时相关的参数

关于机械硬盘和千兆网络¶
Nebula Graph 设计时主要针对的硬件设备是 NVMe SSD 和万兆网。没有专门对于机械磁盘和千兆网络做过适配,以下是一些需调整的参数:

etc/nebula-storage.conf:
--raft_rpc_timeout_ms= 5000 至 10000
--rocksdb_batch_size= 4096 至 16384
--heartbeat_interval_secs = 30 至 60
--raft_heartbeat_interval_secs = 30 至 60
Spark Writer:

rate: {
      timeout: 5000 至 10000
    }
go-importer:
batchSize: 10 至 50
concurrency: 1 至 10
channelBufferSize:100 至 500
partition 值为全集群硬盘数量 2 倍

这些建议参数就是我写的,不过大多数情况还是不够。
我的经验是HDD要调出来很难。你也可以试试。

1 个赞

多谢了,那我还是用SSD吧

2 个赞

7.VID选择的问题,我也讨论过,现在想想,大于等于hash函数的定长比较合适,小于定长的直接使用,大于定长的使用hash这样大部分数据都是用的定长的,也解决了超过定长主键的问题。@mover你觉得呢

@norainsunshine 我是这么考虑的:
1)定长的fix_string好处是这个string跟我们的业务语义是对应的,查询时可以直接使用字符串。但是业务的唯一标识符往往比较长,那么每页存储的索引项会少很多,索引项比较和缓存的效率会低一些。
2)如果用VID=hash(主键)的int64值作为主键,可以避免上面的问题,只是查询前需要先计算hash(主键),但是既然是hash运算,就会存在冲突,vid必须是唯一的吧。
3)如果像mysql那样,使用类似自增的int64值,查询时还是需要为业务主键建立一个索引表,查到对应的vid值,然后使用vid值查询相应的数据,这种情况下还不如直接使用主键作为vid效率高。不知道nebula graph增加fix_string vid类型是不是基于这些考虑。
4)不过图内部遍历时,int64类型的vid遍历效率应该会高些吧

我们的开发人员或者是有相关测试或实践经验的朋友怎么认为的呢?

1 个赞

现在觉得用hash是比较合适的,VID必须全局唯一。这个在一般数据库里很难保证

请问用hash是什么意思?VID=hash(主键)吗?

多谢共享的链接,但是我看了这个视频后,并没有解答所有的问题。尤其是2)和3)两个关于写入和读取过程的问题,请问哪位朋友可以帮我解答下么?我觉得这两个问题对我设计和使用挺重要的,谢了先

2)如果用VID=hash(主键)的int64值作为主键,可以避免上面的问题,只是查询前需要先计算hash(主键),但是既然是hash运算,就会存在冲突,vid必须是唯一的吧。

如果用 hash 方式生成 int64 VID:在有 10 亿个点的情况下,发生碰撞的概率大约是 1/10。边的数量与碰撞的概率无关。

3)如果像mysql那样,使用类似自增的int64值,查询时还是需要为业务主键建立一个索引表,查到对应的vid值,然后使用vid值查询相应的数据,这种情况下还不如直接使用主键作为vid效率高。不知道nebula graph增加fix_string vid类型是不是基于这些考虑。

用主键做VID,会浪费点内存和硬盘。不过放主键总是比放data cache有价值。

您好,请问如何在flink-connector里,通过hash方法生成一个int64,咱们官方的包有提供相关方法吗?