Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Datastax Cassandra结果集与Java 8并行流一起使用-快速_Java_List_Cassandra_Resultset_Datastax - Fatal编程技术网

将Datastax Cassandra结果集与Java 8并行流一起使用-快速

将Datastax Cassandra结果集与Java 8并行流一起使用-快速,java,list,cassandra,resultset,datastax,Java,List,Cassandra,Resultset,Datastax,我使用Datastax驱动程序从Cassandra获取了很多行,我需要尽快处理它们 我已经研究过如何使用List::parallelStream().forEach(),这在一开始似乎很好,因为ResultSet的行为非常类似于列表,但遗憾的是,我无法直接在ResultSet上使用parallelStream()。要使其工作,我首先必须使用ResultSet::all(),这确实很慢-我假设它会迭代每个元素 ResultSet rs = this.getResultSet(); // Takes

我使用Datastax驱动程序从Cassandra获取了很多行,我需要尽快处理它们

我已经研究过如何使用
List::parallelStream().forEach()
,这在一开始似乎很好,因为
ResultSet
的行为非常类似于
列表
,但遗憾的是,我无法直接在
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
ResultSet rs=this.getResultSet();//拿
要使其工作,我首先必须使用ResultSet::all(),这确实很慢

ResultSet.all()
将使用服务器端分页获取所有行。您可以使用
语句控制页面大小。setFetchSize()

有没有更快的方法可以处理结果集的每一行

这取决于你的疑问,是什么?如果您正在执行完整分区扫描,则只有几台计算机在执行此任务,但如果您正在从多个分区获取数据,则可以尝试使用多个查询对其进行并行化,每个分区一个查询。您可以尝试以下方法:

ResultSet rs = this.getResultSet(); // Takes <1 second

StreamSupport.stream(
    Spliterators.spliteratorUnknownSize(
                rs.iterator(), Spliterator.ORDERED), false)
       .parallel().forEach(this::processRow);
迭代器中实现的方法
next()
将轮询行队列

public Row next() {
    return Row.fromData(metadata, rows.poll());
}

这意味着数据处理不需要等待21秒就可以开始处理第一行。

的结果与作者描述的几乎相同。 我的解决方案是将FetchSize设置为更大的值。据我所知,默认值是5000。获取所有信息并迭代,我花了约25秒的时间。使用.setFetchSize(50000)进行迭代需要0.8秒。我甚至都不相信。使用简单foreach循环进行迭代

我的代码:

String sql = "...."
prepearedSql = session.prepare(sql);
Statement statement = prepearedSql.bind().setValues(...).setFetchSize(50000);
ResultSet result = session.execute(statement);
for (Row row : result)
    {...

执行第一个建议仍然需要>20秒来处理行。似乎在后端,线程无法同时读取结果集。我明白了。很遗憾听到这个消息。这不是处理中的并行性问题。我确信它工作正常。只是从数据库中获取行太慢了。根据阿姆达尔定律,当链式计算的并行部分相对于顺序计算而言很小时,整体加速比很小。出于好奇,rList的顺序处理需要多少时间?查看计时数据,瓶颈不是行的处理,而是行的检索。因此,并行行处理将给您带来一个相当小的改进。在我看来,您应该考虑优化查询/schema/cluster setup/network。这里不是这样吗?与您使用的驱动程序无关,问题是相同的:您通过驱动程序向C*提交查询;C*处理查询并计算结果集的行;C*将结果行发送回驱动程序(在@doanduyhai指出的页面中)。只要驱动程序使第一行可用,客户端就可以开始处理行(
one()
返回第一行)。因此,您可以开始并行处理行,而C*会发送更多行,从而有效地并行处理过程。但总的来说,你的速度永远不会超过C*向你发送结果最后一行所需的时间。你的意思是,C*向你发送结果最后一行所需的时间是这里的瓶颈?我想我唯一能绕过这个问题的方法就是对模式和查询进行更改?是的,没错。为
rs.all()
测量的21秒是C*计算和传递组成结果集的行所需的累计时间,包括与wire格式之间的转换。处理结果集只需3秒钟,如果您现在通过调用
rs.all()
等待所有行的传递,而在第一行可用时立即开始处理行,则可能会对总体处理时间产生近乎疏忽的影响(请参见“管道”)。所以,开始优化你花了大部分时间的地方。在C*面。
String sql = "...."
prepearedSql = session.prepare(sql);
Statement statement = prepearedSql.bind().setValues(...).setFetchSize(50000);
ResultSet result = session.execute(statement);
for (Row row : result)
    {...