我有下一个代码:
sc.parquetFile("some large parquet file with bc").registerTempTable("bcs")
sc.parquetFile("some large parquet file with imps").registerTempTable("imps")
val bcs = sc.sql("select * from bcs")
val imps = sc.sql("select * from imps")
我想这样做:
bcs.map(x => wrapBC(x)).collect
imps.map(x => wrapIMP(x)).collect
但是当我这样做时,它不会运行异步。我可以用Future做这件事:
val bcsFuture = Future { bcs.map(x => wrapBC(x)).collect }
val impsFuture = Future { imps.map(x => wrapIMP(x)).collect }
val result = for {
bcs <- bcsFuture
imps <- impsFuture
} yield (bcs, imps)
Await.result(result, Duration.Inf) //this return (Array[Bc], Array[Imp])
我想在没有未来的情况下这样做,我该怎么做?
答案 0 :(得分:2)
更新这最初是在问题更新之前编写的。鉴于这些更新,我同意@stholzm's answer在这种情况下使用cartesian
。
确实存在有限数量的操作,这些操作将为FutureAction[A]
生成RDD[A]
并在后台执行。这些内容在AsyncRDDActions上提供,只要您导入SparkContext._
,任何RDD
都可以根据需要隐式转换为AysnchRDDAction
。对于您的特定代码示例:
bcs.map(x => wrapBC(x)).collectAsync
imps.map(x => wrapIMP(x)).collectAsync
除了在背景中评估DAG到行动之外,生成的FutureAction
还有cancel
方法来尝试提前结束处理。
这可能与您的想法无关。如果目的是从两个来源获取数据然后合并它们,您更有可能想要加入或分组RDD 。为此,您可以查看PairRDDFunctions中可用的函数,通过隐式转换再次在RDD上可用。
如果目的不是让数据图表进行交互,那么根据我的经验,然后同时运行批处理可能只会减慢两者的速度,尽管这可能是集群配置的结果。如果资源管理器被设置为以FIFO顺序对集群进行垄断(独立和YARN模式中的默认值,我相信;我对Mesos不确定)那么每个异步收集都会争用为了这种垄断,彼此执行任务,然后再次争夺下一个执行阶段。
将此与使用Future
来阻止对下游服务或数据库的阻塞调用进行比较,例如,所讨论的资源是完全独立的,或者通常具有足够的资源容量来并行处理多个请求而不会发生争用。
答案 1 :(得分:1)
更新:我误解了这个问题。期望的结果不是笛卡儿积Array[(Bc, Imp)]
。
但是我认为单map
次调用需要多长时间并不重要,因为只要你添加其他转换,Spark就会尝试以有效的方式组合它们。只要您只在RDD上链接转换,数据就不会发生任何变化。当您最终应用操作时,执行引擎将找到生成所请求数据的方法。
所以我的建议是不要过多考虑中间步骤并尽可能避免collect
,因为它会将所有数据提取到驱动程序中。
您似乎正在自己制作笛卡尔产品。请尝试cartesian
:
val bc = bcs.map(x => wrapBC(x))
val imp = imps.map(x => wrapIMP(x))
val result = bc.cartesian(imp).collect
请注意,collect
在最终RDD上调用,不再在中间结果上调用。
答案 2 :(得分:0)
您可以使用$html_string = '<!-- start block -->
<p>Hello world etc</p>
<div>something</div>
<div>something2</div>
<!-- end of block -->
<div>something3</div>
';
$html = str_get_html($html_string);
// start point
$start = $html->find('*');
$output = ''; $go = false;
foreach($start as $e) {
if($e->innertext === '<!-- start block -->') {
$go = true;
continue;
} elseif($e->innertext === '<!-- end of block -->') {
break;
}
if($go) {
$output .= $e;
}
}
echo $output;
来解决此问题。例如:
union
如果要使用sortBy或其他操作,可以使用trait或main类的继承。