我在Scala中编写了一个相对简单的Spark作业,它从S3读取一些数据,执行一些转换和聚合,最后将结果存储到存储库中。
在最后阶段,我有一个我的域模型的RDD,我想将它们分组成一大块元素,以便我可以在我的存储库中进行一些大量插入。
我使用RDDFunctions.sliding
方法来实现这一点并且它的工作几乎没问题。这是我的代码的简化版本:
val processedElements: RDD[DomainModel] = _
RDDFunctions.fromRDD(processedElements)
.sliding(500, 500)
.foreach { elementsChunk =>
Await.ready(repository.bulkInsert(elementsChunk), 1.minute)
}
问题是,例如,如果我有1020个元素,那么只有1000个元素在我的存储库中结束。如果窗口大小大于剩余元素的数量,滑动看起来像忽略任何其他元素。
有什么方法可以解决这个问题吗?如果没有,是否有其他方法可以在不使用RDDFunctions.sliding
的情况下实现相同的行为?
答案 0 :(得分:0)
你能不能只使用// set up our data series with 50 random data points
var seriesData = [
[],
[],
[]
];
var random = new Rickshaw.Fixtures.RandomData(150);
var graph, slider, hoverDetail, legend, shelving, order, highlight;
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
graph = new Rickshaw.Graph({
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
stroke: true,
preserve: true,
series: [{
color: "#c05020",
data: seriesData[0],
name: 'New York'
}, {
color: "#30c020",
data: seriesData[1],
name: 'London'
}, {
color: "#6060c0",
data: seriesData[2],
name: 'Tokyo'
}]
});
graph.render();
slider = new Rickshaw.Graph.RangeSlider({
graph: graph,
element: $("#slider")[0]
});
hoverDetail = new Rickshaw.Graph.HoverDetail({
graph: graph
});
legend = new Rickshaw.Graph.Legend({
graph: graph,
element: $("#legend")[0]
});
shelving = new Rickshaw.Graph.Behavior.Series.Toggle({
graph: graph,
legend: legend
});
order = new Rickshaw.Graph.Behavior.Series.Order({
graph: graph,
legend: legend
});
highlight = new Rickshaw.Graph.Behavior.Series.Highlight({
graph: graph,
legend: legend
});
和手动批量管理?
foreachPartition
答案 1 :(得分:0)
根据RDDFunctions doc,如果窗口大小超过剩余项目数,那么Spark的sliding
(与Scala不同)会生成空的RDD。 Spark也不具有Scala grouped
的等价性。
如果您知道要创建的群组数量,则可能适用的解决方法是使用modulo
过滤器拆分RDD。以下是将RDD分为5组的简单例子:
val rdd = sc.parallelize(Seq(
(0, "text0"), (1, "text1"), (2, "text2"), (3, "text2"), (4, "text2"), (5, "text5"),
(6, "text6"), (7, "text7"), (8, "text8"), (9, "text9"), (10, "text10"), (11, "text11")
))
def g(n:Int)(x: Int): Boolean = { x % 5 == n }
val rddList = (0 to 4).map( n => rdd.filter(x => g(n)(x._1)) )
(0 to 4).foreach(n => rddList(n).collect.foreach(println))
(0,text0)
(5,text5)
(10,text10)
(1,text1)
(6,text6)
(11,text11)
(2,text2)
(7,text7)
(3,text2)
(8,text8)
(4,text2)
(9,text9)