【发布时间】:2016-05-15 11:49:24
【问题描述】:
我正在使用 Datastax 驱动程序从 Cassandra 获取大量行,我需要尽快处理它们。
我已经研究过使用List::parallelStream().forEach(),起初看起来很棒,因为ResultSet 的作用很像List,但遗憾的是我无法直接在ResultSet 上使用parallelStream()。为了让它工作,我首先必须使用 ResultSet::all() 这真的很慢 - 我假设它会迭代每个元素。
ResultSet rs = this.getResultSet(); // Takes <1 second
// Convert the ResultSet to a list so as I can use parallelStream().
List<Row> rsList = rs.all(); // Takes 21 seconds
rsList.parallelStream().forEach(this::processRow); // Takes 3 seconds
有没有更快的方法可以处理结果集的每一行?
【问题讨论】:
-
出于好奇,rList的顺序处理需要多少时间?查看您的时序图,您的瓶颈不是行的处理,而是它们的检索。所以并行化行处理会给你一个相当小的改进。在我看来,您似乎应该考虑优化您的查询/模式/集群设置/网络。
-
我来自 PHP 背景,所以我习惯于在调用 execute() 后包含行的结果集。这里不是这样吗?
-
与您使用的驱动程序无关,问题是一样的:您通过驱动程序向 C* 提交查询; C* 处理查询并计算结果集的行; C* 将结果行发送回驱动程序(在 @doanduyhai 指出的页面中)。一旦驱动程序使第一行可用,客户端就可以开始处理行(
one()返回第一行)。因此,您可以在 C* 发送更多行的同时开始并行处理行,从而有效地并行化该过程。但总的来说,您永远不会比 C* 向您发送结果的最后一行所需的时间更快。 -
您的意思是,C* 发送到行所花费的时间是这里的瓶颈?我想解决这个问题的唯一方法是更改架构和查询?
-
是的,完全正确。您为
rs.all()测量的 21 秒是 C* 计算和传递构成结果集的行所花费的累积时间,包括与有线格式之间的转换。处理结果集只需要 3 秒,如果您现在通过调用rs.all()等待所有行交付,而是在第一行可用时立即开始处理行,则可能对整体处理时间的影响几乎可以忽略不计(参见“流水线”)。因此,开始优化您花费最多时间的地方。哪个在 C* 端。
标签: java list cassandra resultset datastax