一些背景:我们正在Ignite集群附近构建一个机器学习场。用例的一部分是生成训练数据集,它们是巨大的矩阵(理论上多达数十亿行x数千列),在Ignite缓存中每个数据条目一行。
我们正在使用SqlQuery
来获取每个节点上与本地谓词匹配的记录,然后遍历记录,生成向量,并将它们写入外部存储以供进一步使用。每个节点独立地导出数据,因此对于32个节点,我们最终得到32个导出的数据集。
问题:生成较小的数据集可以正常运行,但是生成较大的数据集(预计每个节点将返回10M +行的查询)基本上会杀死整个集群,由于OOME和GC地狱而炸毁了节点。我们查看了Ignite文档(https://apacheignite-sql.readme.io/docs/performance-and-debugging#result-set-lazy-load)的“性能和调试”部分,尝试了惰性结果集和页面大小设置。不。
调查(分析,内存转储,调试器等)表明,即使我们使用QueryCursor
和迭代,查询的结果集也会在代码读取第一行之前完全加载到内存中。 Query#pageSize
和SqlFieldsQuery#setLazy
似乎对此没有任何影响。深入研究发现,H2(Ignite索引正在使用)在结果集中根本不支持服务器端游标,并且只能配置为将记录缓冲到磁盘上(即使使用SSD,这也是非性能的)。起动机)。仔细阅读Ignite源代码表明,Query#pageSize
和SqlFieldsQuery#setLazy
仅用于分布式查询/扫描查询,但Ignite仍将节点上的结果集完整读取到内存中。
S。这些是我们想到的补救措施:
h2.maxMemoryRows
设置较小的值。似乎是一个愚蠢的解决方案(通过磁盘上的缓冲区在同一JVM中的内存到内存吗?真的吗?)。SQLQuery
/ SQLFieldsQuery
,绕过H2,使用ScanQuery
。这是一项繁重的工作(必须解析谓词并将其编译为IgniteBiPredicate
,而且这些是全表扫描,因此没有索引/优化,这种排序使整个过程变得毫无意义)。问题:我们的评估是否正确,查询结果流式传输对本地查询而言不是问题?还有其他更明智的解决方法吗?
如果他们读了此书,将会感谢Ignite同志的一些见识。预先感谢!
更新:如果很重要,则群集为8个节点,如下所示:
Architecture: x86_64
CPU(s): 32
Model name: Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz
CPU MHz: 2345.904
BogoMIPS: 4600.05
Hypervisor vendor: Xen
Virtualization type: full
RAM: 240Gb
这些被指定为具有临时卷的EC2-s,用于Ignite /data
安装。
答案 0 :(得分:0)
lazy
绝对可以做任何事情:对于SELECT * FROM cache
查询,是集群故障和正常运行之间的区别。 page size
应该与lazy
一起工作。
您可以显示查询吗?另外,我不确定它是否真的适用于本地查询。
答案 1 :(得分:0)
在看似已解决问题之后更新此内容。
注意:问题是关于本地查询的。
似乎将SqlFieldsQuery
与'lazy'一起使用有助于本地查询。本地SqlQuery
似乎忽略了lazy
标志。