共计 3207 个字符,预计需要花费 9 分钟才能阅读完成。
摘要:在本文中 360 数科的周鹏具体解说了业务从 JanusGraph 迁徙到 Nebula Graph 带来的性能晋升,在机器资源不到之前 JanusGraph 配置三分之一的状况下,业务性能晋升至多 20 倍。
本文作者系 360 数科开发工程师:周鹏
迁徙背景
咱们之前图数据用的是单机版的 AgensGraph, 前面因为单机带来的性能限度问题,迁徙到了分布式数据库 JanusGraph,具体的迁徙信息能够看我之前的一篇文章《百亿级图数据 JanusGraph 迁徙之旅》。然而随着数据量和业务调用量的减少,新的问题又呈现了——单次查问的耗时很高个别业务场景曾经到了 10s,数据量略微多点,逻辑简单点的查问耗时也在 2~3s 左右,这重大影响了整个业务流程的性能和相干业务的倒退。
JanusGraph 的架构决定了单次耗时高,外围的起因在于它的存储依赖内部,本身不能很好地管制内部存储,咱们生产环境用的便是 HBase 集群,这导致所有的查问没法下推到存储层进行解决,只能把数据从 HBase 查问到 JanusGraph Server 内存再做相应的过滤。
举个例子,查问一层关联关系年龄大于 50 岁的用户,如果一层关联有 1,000 人,年龄大于 50 岁的只有 2 集体。介于 JanusGraph 查问申请发送到 HBase 时做不了一层关联顶点属性的过滤,咱们不得不通过并发申请去查问 HBase 获取这 1,000 人的顶点属性,再在 JanusGraph Server 的内存做过滤,最初返回给客户端满足条件的 2 个用户。
这样做的问题就是磁盘 IO、网络 IO 节约很大,而且查问返回的大多数据在而后查的查问并未用到。咱们生产环境用的 HBase 为 19 台高配 SSD 服务器的,具体的网络 IO、磁盘 IO 应用状况如下图:
咱们比照雷同的业务场景,然而只有 6 台雷同配置的 SSD 服务器 Nebua Graph 的磁盘 IO 和网络 IO 状况如下:
Nebula Graph 性能的确优良太多,而且是在机器资源只有之前 Hbase 集群 30% 的状况下。咱们再来看下业务场景下的耗时状况,之前业务场景中查问耗时须要 2~3s 状况的在 Nebula Graph 这边 100ms 左右返回了,之前须要 10~20s 状况的业务场景当初也根本在 2s 就能返回,并且均匀耗时也根本在 500ms 左右就能搞定,性能晋升至多 20 倍以上 :)
就冲下面的这些数据,如果你还在用 JanusGraph,就应该立马把这篇文章转发给你的领导,并立个项开始迁徙到 Nebua Graph ????
历史数据迁徙
数据迁徙这块,因为咱们的数据量比拟大,20 亿左右的顶点,200 亿左右的边,好在 Nebula Graph 提供 Spark 导入工具——Spark Writer,整个数据导入过程还算比拟晦涩。这里有个可分享教训,过后应用 Spark 导入工具采纳异步形式导入导致了不少 error,略微改下导入形式换成同步写入就没问题了。另外一个教训是对于 Spark 的,如果导入的数据量比拟大,对应的 partitions 须要设置大一点,咱们就设置过 8w 个 patitions。如果你设置的 partitions 比拟小,单个 partition 的数据量便会比拟大,容易导致 Spark 工作 OOM Fail。
查问调优
咱们当初生产环境 Nebula Graph 用的是 1.0 的版本,生产环境上 ID 生产咱们用的是 hash 函数,uuid 导入数据会很慢,前面官网也不会再反对 uuid。
在咱们的生产环境主要参数调优配置如下,次要是 nebula-storage 须要调优
# The default reserved bytes for one batch operation
--rocksdb_batch_size=4096
# The default block cache size used in BlockBasedTable.
# The unit is MB. 咱们生产服务器内存为 128G
--rocksdb_block_cache=44024
############## rocksdb Options ##############
--rocksdb_disable_wal=true
# rocksdb DBOptions in json, each name and value of option is a string, given as "option_name":"option_value" separated by comma
--rocksdb_db_options={"max_subcompactions":"3","max_background_jobs":"3"}
# rocksdb ColumnFamilyOptions in json, each name and value of option is string, given as "option_name":"option_value" separated by comma
--rocksdb_column_family_options={"disable_auto_compactions":"false","write_buffer_size":"67108864","max_write_buffer_number":"4","max_bytes_for_level_base":"268435456"}
# rocksdb BlockBasedTableOptions in json, each name and value of option is string, given as "option_name":"option_value" separated by comma
--rocksdb_block_based_table_options={"block_size":"8192"}
--max_handlers_per_req=10
--heartbeat_interval_secs=10
# 新增加参数
--raft_rpc_timeout_ms=5000
--raft_heartbeat_interval_secs=10
--wal_ttl=14400
--max_batch_size=512
# 参数配置减小内存应用
--enable_partitioned_index_filter=true
--max_edge_returned_per_vertex=10000
Linux 机器的调优次要就是把服务的 swap 敞开掉,开启后会因为磁盘 IO 影响查问性能。另外对于 minor compact 和 major compact 调优,咱们生产环境是开启 minor compact 敞开 major compact。敞开 major compact 次要是因为这个操作很占磁盘 IO,并且很难通过线程数(--rocksdb_db_options={"max_subcompactions":"3","max_background_jobs":"3"
})管制,后续 Nebula Graph 官网有打算优化这块。
最初,来重点提下 max_edge_returned_per_vertex
这个参数,能想到这个参数 Nebula Graph 不愧是图数据行业的老司机——咱们之前的图查问始终受到超级节点的困扰,线上环境如果查问遇到这种关联几百万数据的超级节点能间接把 JanusGraph 的 HBase 集群查崩掉(咱们生产环境呈现过几次)。之前在查问 JanusGraph 的 Gremlin 语句上加各种 limit 限度都没能很好的解决这个问题,在 Nebula Graph 有了这个 max_edge_returned_per_vertex
参数,数据在最底层存储层间接做了过滤,生产环境就不会再有这种超级节点的困扰,就这一点就应该给 NebulaGraph 一个 FIVE STAR!
本文首发于 Nebula Graph 论坛, 浏览本文的你有任何疑难,欢送返回论坛和作者进行探讨,原帖传送门:https://discuss.nebula-graph.com.cn/t/topic/1172