我有一个Spark作业,它读取一个镶有大约150.000.000个键/值条目的镶木地板文件。
SparkConf conf = new SparkConf();
conf.setAppName("Job");
JavaSparkContext jsc = new JavaSparkContext(conf);
SQLContext sql = new SQLContext(jsc);
DataFrame df = sql.read().parquet(path);
我的目标是将键/值对写入HBase,但是我遇到堆内存问题,我怀疑这不是最好的方法。我想将计算推送到集群,但我无法弄清楚如何跳过收集部分。现在我的代码看起来像这样:
HBaseClient client = HbaseWrapper.initClient();
df.collectAsList().stream().forEach(row -> {
try {
HbaseWrapper.putRows(client, row);
} catch (Exception e) {
e.printStackTrace();
}
});
jsc.stop();
我试图在没有流媒体的情况下首先收集列表,然后将其写下来,但这也需要永远。
任何见解都表示赞赏。
答案 0 :(得分:2)
您收到OOM错误,因为collectAsList会将所有数据发送给驱动程序。
要解决此问题,您可以使用foreachPartitions,因此您将并行流式传输到Hbase。
df.toJavaRDD().foreachPartition(new VoidFunction<Iterator<Row>>() {
@Override
public void call(Iterator<Row> t) throws Exception {
try {
HBaseClient client = HbaseWrapper.initClient();
while(t.hasNext()){
Row row = t.next();
HbaseWrapper.putRows(client, row);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});