我正在尝试创建一个火花应用程序,该应用程序将获取 lat , long , timestamp 点的数据集,并增加单元数在网格单元内。网格由以 lon , lat 和 time 为z轴的3d单元组成。
现在我已经完成了该应用程序,它已经完成了应有的工作,但是扫描整个数据集(〜9g)需要花费数小时。我的集群由3个节点组成,每个节点具有4个内核,每个内核8g,而我目前正在使用6个具有1个内核和2g内核的执行程序。
我想我可以优化代码很多,但是我的代码中是否有一个大错误导致这种延迟?
//Create a JavaPairRDD with tuple elements. For each String line of lines we split the string
//and assign latitude, longitude and timestamp of each line to sdx,sdy and sdt. Then we check if the data point of
//that line is contained in a cell of the centroids list. If it is then a new tuple is returned
//with key the latitude, Longitude and timestamp (split by ",") of that cell and value 1.
JavaPairRDD<String, Integer> pairs = lines.mapToPair(x -> {
String sdx = x.split(" ")[2];
String sdy = x.split(" ")[3];
String sdt = x.split(" ")[0];
double dx = Double.parseDouble(sdx);
double dy = Double.parseDouble(sdy);
int dt = Integer.parseInt(sdt);
List<Integer> t = brTime.getValue();
List<Point2D.Double> p = brCoo.getValue();
double dist = brDist.getValue();
int dur = brDuration.getValue();
for(int timeCounter=0; timeCounter<t.size(); timeCounter++) {
for ( int cooCounter=0; cooCounter < p.size(); cooCounter++) {
double cx = p.get(cooCounter).getX();
double cy = p.get(cooCounter).getY();
int ct = t.get(timeCounter);
String scx = Double.toString(cx);
String scy = Double.toString(cy);
String sct = Integer.toString(ct);
if (dx > (cx-dist) && dx <= (cx+dist)) {
if (dy > (cy-dist) && dy <= (cy+dist)) {
if (dt > (ct-dur) && dt <= (ct+dur)) {
return new Tuple2<String, Integer>(scx+","+scy+","+sct,1);
}
}
}
}
}
return new Tuple2<String, Integer>("Out Of Bounds",1);
});
答案 0 :(得分:0)
像这样运行Spark映射可能导致成本增加的最大因素之一与RDD上下文外部的数据访问有关,这意味着驱动程序交互。在您的情况下,至少有4个变量访问器在其中发生:brTime
,brCoo
,brDist
和brDuration
。看来您正在通过String#split
进行某些行解析,而不是利用内置函数。最后,scx
,scy
和sct
都是为每个循环计算的,尽管它们仅在其数值对应对象通过一系列检查后才返回,这意味着浪费了CPU周期和额外的时间。 GC。
在没有实际审查工作计划的情况下,很难说上述内容是否可以使绩效达到可接受的水平。查看历史服务器应用程序日志,看看是否有任何阶段正在占用您的时间-一旦您确定了罪魁祸首,那实际上就是需要优化的地方。
答案 1 :(得分:0)
我尝试了mappartitionstopair,还移动了scx,scy和sct的计算,以便仅在点通过条件时才进行计算。应用程序的速度仅17分钟就得到了极大的改善!我相信mappartitionsopair是最大的因素。非常感谢Mks和bsplosion!
答案 2 :(得分:0)
尝试使用mapPartitions可以更快地看到此示例链接;另一件事是将这部分代码放在循环timeCounter之外