spark-connector 导入速度太慢

提问参考模版:

  • nebula 版本:v2.6.1
  • 部署方式:分布式
  • 安装方式:RPM
  • 是否为线上版本:Y
  • 硬件信息
    • 磁盘( 推荐使用 SSD)
    • CPU、内存信息
  • 问题的具体描述
    最近跑了一段时间 读取hive 用 spark-connector 导入数据,发现速度太慢了,还没有importer 导入csv 的速度快。
    具体导入了一个节点3.2亿,两种边分别是2亿,1.6亿
    相关配置:
    space: 30 分区,3 replica factor。
    导入的代码:
     df = df.repartition(300)
    
    print(df.rdd.getNumPartitions())

    df.write.format("com.vesoft.nebula.connector.NebulaDataSource")\
    .mode("overwrite")\
    .option("timeout", 300000)\
    .option("connectionRetry", 1)\
    .option("executionRetry", 2)\
    .option("vidPolicy", "")\
    .option("metaAddress", metaHost[cluster])\
    .option("graphAddress", graphHost[cluster])\
    .option("user", "root")\
    .option("passwd", "nebula")\
    .option("type", "vertex")\
    .option("spaceName", "Relation")\
    .option("label", entity)\
    .option("vertexField", "vid")\
    .option("batch", 2000)\
    .option("writeMode", "insert").save()   # delete to delete vertex

    print(f"write nebula {entity} vertics done")

spark 提交到yarn-cluster 的参数
num-executor: 5, executor-cores: 20

nebula-storage.conf 的部分配置

############## rocksdb Options ##############
# 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":"4","max_background_jobs":"4"}
# 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"}

# Whether or not to enable rocksdb's statistics, disabled by default
--enable_rocksdb_statistics=false

瓶颈是写入耗时太久:

请问可以调节哪些参数,提高导入速到? 关闭auto compaction 吗?

1 个赞

https://github.com/vesoft-inc/nebula-spark-connector readme中的性能是2.2亿数据是不到3分钟,提高导入速度的参数:
关闭auto compaction
提高batch数
提高分配的总cores数

加几台机器比一下
spark是给分布式用的

batch 现在时2000,我试过3000, 先试试提高到5000
现在可以看到单个job 的导入时间也很长,提高cores 应该解决不了这个问题吧,max 47min median 36min 和README 中相差甚远


auto compaction 因为时线上环境,最后在尝试这种方案

这个集群nebula 是三节点的,nebula 增加节点吗?

num-executor 数量加一些

.option(“graphAddress”, graphHost[cluster]) 是向3个吗

是3个,num_executor 要再增加吗? 现在repartition 之后是300个task,现在logical process 是100, 增加到多少合适?

batch 增加并没有提高多少。
我试了下取消repartition, DataFrame 的分区120,分配了120个logical processes (num-executor * executor-cores), 但是实际上单个任务的写入还是比较慢,成为瓶颈。

README 的测试中 用了什么参数优化吗

README的测试还比较简单,就关闭了storaged的自动compact 。
你的磁盘是hdd还是ssd?
README中测试用的LDBC数据,边数据几乎没有属性的,如果你的数据中有很多属性,那不能简单的通过条数来比较性能的,还要考虑数据的size

  • SSD
  • 边和点平均五六个属性,每个属性平均十个长度的字符串
  • 如果关闭了自动的compact 时间久了,对查询性能影响会不会比较大?(现在一周有两次的全量 compaction 任务,每天有百万的数据写入) 对compact 有什么较好的建议吗?
  • 现在看起来瓶颈再单任务的写入,目前还有其他调优手段吗?

如果是你们的线上环境还是不要关闭自动compact了,可以调整Nebula Storage的参数:

--rocksdb_block_cache : 数据在内存缓存大小,默认是4MB,可以设置到当前内存的1/3
--rocksdb_db_options={"max_subcompactions":"48","max_background_jobs":"48"} 打开自动compaction时加快速度,该参数是调整compaction的并发的
--wal_ttl=600  大量数据导入时,该参数需调小,不然可能会因为产生大量的wal导致磁盘空间被撑满
1 个赞

我昨天测试了关闭auto compact 确实原来要1.5 h 的单个点导入,现在只需要0.5 h。
但是产生的问题确实就是wal 回收过慢,硬盘不足告警。
–rocksdb_block_cache 这个之前调整过了
后面两个参数调整试试看

这个问题调整这个参数 --wal_ttl=600

1 个赞

了解,谢谢, 不仅仅wal 比较多,data 目录 数据量比正常也大不少。
前面可以理解,后面data 目录不太理解,全量的导入没有delete 操作的

是有存储放大的,你是边数据比较多吗,边数据越多放大比越大的

边比较多,compact 之后会目录正在变小

data目录多大?2~3倍的存储空间放大是复合预期的
你硬盘是不是很小啊

500G data + 300G 左右wal, compact 之后197G + 几百兆 wal
2T 硬盘,还有其他空间的数据, 正常情况下硬盘使用只有50%

--rocksdb_db_options={"max_subcompactions":"48","max_background_jobs":"48"} 打开自动compaction时加快速度,该参数是调整compaction的并发的
这个参数调整了下,导致io 拉满了,影响了其他服务,迫不得已 把storage 停了,这个线程数量太高了:sweat_smile:

这边我还有一个疑问
如果未关闭auto_compaction ,用importer tool 和 nebula-spark-connector 反而importer tool 的表现更优异,表现为:

  1. nebula P95 storage insert 等相关指标,importer tool 导入时不会超过阈值告警,spark-connector 会告警
  2. 导入时长,importer 会更快些

这个是预期的情况吗

分别用 importer 和 connect 是先后导入的么?如果用 importer 导入,导入数据大概有多大?

底层是 LSM tree,开了自动 compact 的话,还和你存量数据大小有关系。
你可以敲一下 http://192.168.15.8:19779/rocksdb_property?space=sf100&property=rocksdb.levelstats
把 ip 换成 storage 的,space 换成你的 space,然后分别导入前,看一下存量数据。

1 个赞