在没有收集的情况下在Java中迭代Spark DataFrame

时间:2017-03-08 15:27:21

标签: java loops apache-spark dataframe apache-kafka

我正在使用Spark 1.6.1

我有一个DataFrame需要迭代并将每一行写入Kafka。截至目前,我正在做这样的事情:

Producer<String><String> message;
for(Row x: my_df.collect()){
    kafka_message = new Producer<String><String>(topic, String.valueOf(x))
    my_kafka_producer.send(kafka_message);
}

这里的问题是,collect将数据发送给驱动程序,然后推送到kafka。鉴于我有大约250个执行程序,我的1个驱动程序无法有效地处理工作负载。所以,我想知道如何在我的执行器上迭代数据帧。这将需要避免执行collect()。我发现了一篇粗略解释如何操作的文章,但不幸的是,他们与GitHub的链接实际上已经过期,所以我无法找到如何实现它。

文章供参考: https://pythagoreanscript.wordpress.com/2015/05/28/iterate-through-a-spark-dataframe-using-its-partitions-in-java/comment-page-1/

1 个答案:

答案 0 :(得分:3)

在Java中,您可以尝试类似下面的内容。扩展AbstractFunction1

import scala.runtime.AbstractFunction1;

abstract class MyFunction1<T,R> extends AbstractFunction1<T, R> implements Serializable {
}

现在为您的Dataframe致电foreachPartition,如下所示。

import scala.collection.Iterator;
import scala.runtime.BoxedUnit;

df.foreachPartition(new MyFunction1<Iterator<Row>,BoxedUnit>(){
        @Override
        public BoxedUnit apply(Iterator<Row> rows) {
            while(rows.hasNext()){
                //get the Row
                Row row = rows.next();
            }
            return BoxedUnit.UNIT;
        }
    });