exchange中batch的单次写入 NebulaGraph 的最大点数据量是什么意思

在exchange的application.cnf中配置tag有参数batch,其解释为

# 标明数据源中数据分隔方式,默认为英文逗号(,)。
      separator: ","

      # 如果 CSV 文件中有表头,header 设置为 true。
      # 如果 CSV 文件中没有表头,header 设置为 false(默认值)。
      header: false

      # 单次写入 NebulaGraph 的最大点数据量。
      batch: 256

      # Spark 分区数量
      partition: 32

请问batch的大小与入库速度有关系吗?如果不用exchange而是自己使用execute函数进行入库,应该如何模拟batch的效果?

batch 某种程度和入库速度还是有点关系,比如你有 1024 条数据,如果是 256,机器可以支持这个插入量,那就插入 4 次之后好了,如果是支持 512 的话,只要插入 2 次就好了。如果你的机器不支持 512,你的 batch 又设置了 512,可能会导致导入过程中机器没有响应。所以,论坛有些用户反馈服务没响应了,会建议调低 batch。

请问比如我将同类型tag写到一个tag里面,这样比如batch为512,原始数据可能有10000条,这样算是一个batch把?还是原始数据是1024,batch为512,我把512个相同tag的数据合并到一个tag,然后并行发两个请求?

batch,client 向 graphd 发送的一个请求中有多少条数据。在该实践中采用的 LDBC 数据集的 tag 属性不超过 10 个,设置的 batch 数为 2,000。如果 tag 或 edgeType 属性多且字节数多,batch 可以调小,反之,则调大。

batch是设定多少条数据作为一个批次,该值可以根据实际数据的大小进行设定,源码中默认值为2。当一条数据属性少于5个时建议设置1000。

参照上面说法,如果我的属性较多,是否batch需要调小?

我修改了下你的格式,用代码段来展示文字阅读起来有点累(因为有滑动条,我改成引用样式了。

你可以看下之前 harris 的回复 请问yaml文件中 batchSize 和 limit 这两个参数有什么关系,设置多少合适? - #4,来自 HarrisChu 和这个 Nebula-importer工作原理问题 - #2,来自 HarrisChu 了解下 importer 导入的原理。

谢谢您的编辑,我发现我们的操作方法和importer挺像的,我们也是把多个请求拼成一个batch然后发送,只是importer使用的chan,而我们是用了分布式,就是10个进程处理十个批次的数据,然后发送,但是我们的速度可能是importer的10倍耗时,请问是我们发送代码有问题吗?我们是每个进程调用发送代码,我贴一下发送的代码您帮忙看下

def execute(query,task):

connection_pool = ConnectionPool()
assert connection_pool.init([(NEBULA_IP, PORT)], config)
client = connection_pool.get_session(USER, NEBULA_PASSWD)
assert client is not None
resp = client.execute_json(
f"use {task} ; "
)
resp = client.execute_json(
f"{query}"
)
assert resp.is_succeeded(), resp.error_msg()
print(resp)
return resp

@王鑫1 您好!
首先,不同程序语言可能有差异。
其次,从这里也看不出来存在的问题,这个可能得您调试看看。
不清楚您的query是什么,也不清楚您有多少个 client。
有一点可以优化,您这里的 "use {task} ; " 在每次都会执行,这个可以优化下,不过这个不会导致 10 倍的差异,可能还存在其他的问题。

batch 就是一次将多个数据,组成一条插入语句,也就是对应您这里的 query 。

此外, nebula-importer 在哪里还有缺陷,导致你们会考虑自己来实现?

1 个赞

谢谢您的回复,我们觉得importer对于需要设置vid的情况可能需要优化,比如我表达的关系是人拥有身份证,我想使用身份证号(唯一性)来表示人,同时身份证号表示身份证,在这种情况下我无法添加关系“人拥有身份证号“,因为人和身份证号的表示vid都是身份证号,请问这种情况importer可以重新添加一列吗?还是我得手动先添加一列,手动添加列可能浪费时间

不需要呀,你可以 vid 指定列 0,身份属性也指定列 0,像下面这种 index 是可以重复的(我干过,我把编号和 rank 都指定了同一列)

请问在importer中生成batch的时候咱们有什么好的方法吗?我们自己生成的时候最浪费时间的是将json生成string的batch的过程。

 * 把数据按如下格式合并
 * [ {"key":"insert edge `拥有身份证` ()", "values":"\"人_G000002\" -> \"身份证_G000002\" : ()"},
 *     {"key":"insert edge `拥有身份证` ()", "values":"\"人_G000001\" -> \"身份证_G000001\" : ()"},
 *     {"key":"insert vertex `人` (`出生日期`,`教育程度`,`性别`)", "values":""人_G000002" :("19640412","國中畢業","男"), "人_G000001" :("19880808","大学畢業","女")"}
 *    ]
 * 合并为:
 * insert vertex `人` (`出生日期`,`教育程度`,`性别`) values "人_G000002" :("19640412","國中畢業","男"), "人_G000001" :("19880808","大学畢業","女");
 * insert edge `拥有身份证` () values "人_G000002" -> "身份证_G000002" : (), "人_G000001" -> "身份证_G000001" : ();
 * @param allKV
 * @return
 */
上述合并成能入库的string的形式是最耗时间的,请问有什么好的方法合成batch吗?

@王鑫1 生成 batch 的语句,基本逻辑就是字符串的处理。这个可能需要不同的语言来对这块进行优化了,这个可能需要您来压测分析,然后优化了。

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。