Apache spark 将数据帧写入kafka Pypark

Apache spark 将数据帧写入kafka Pypark,apache-spark,pyspark,apache-kafka,spark-dataframe,spark-streaming,Apache Spark,Pyspark,Apache Kafka,Spark Dataframe,Spark Streaming,我有一个spark数据框,我想写信给卡夫卡。我试过下面的片段 from kafka import KafkaProducer producer = KafkaProducer(bootstrap_servers = util.get_broker_metadata()) df = sqlContext.createDataFrame([("foo", 1), ("bar", 2), ("baz", 3)], ('k', 'v')) for row in df.rdd.collect():

我有一个spark数据框,我想写信给卡夫卡。我试过下面的片段

from kafka import KafkaProducer
producer = KafkaProducer(bootstrap_servers = util.get_broker_metadata())
df = sqlContext.createDataFrame([("foo", 1), ("bar", 2), ("baz", 3)], ('k', 'v'))
for row in df.rdd.collect():
    producer.send('topic',str(row.asDict()))
    producer.flush()
这是可行的,但这个代码段的问题是它不可伸缩,因为每次运行collect时,数据都会聚集在驱动程序节点上,并且会减慢所有操作

因为dataframe上的foreach操作可以在工作节点上并行运行。我尝试了下面的方法

from kafka import KafkaProducer
producer = KafkaProducer(bootstrap_servers = util.get_broker_metadata())
df = sqlContext.createDataFrame([("foo", 1), ("bar", 2), ("baz", 3)], ('k', 'v'))
def custom_fun(row):
    producer.send('topic',str(row.asDict()))
    producer.flush()

df.foreach(custom_fun)

这不会导致酸洗错误<代码>PicklingError:无法pickle类型的对象无法理解此错误背后的原因。有人能帮我理解这个错误或提供其他并行解决方案吗

您得到的错误看起来与卡夫卡的写作无关。看起来您在代码中的其他地方使用的是
itertools.count
(如果Spark的源代码中根本没有使用它,那么它当然可能附带了
KafkaProducer
),出于某种原因,它是通过
cloudpickle
模块序列化的。更改卡夫卡编写代码可能根本没有影响。如果
KafkaProducer
是错误源,您应该能够使用
forachPartition
解决此问题:

from kafka import KafkaProducer


def send_to_kafka(rows):
    producer = KafkaProducer(bootstrap_servers = util.get_broker_metadata())
    for row in rows:
        producer.send('topic',str(row.asDict()))  
        producer.flush()

df.foreachPartition(send_to_kafka)
也就是说:

或者提供其他并行解决方案

我建议使用卡夫卡资料。包括Kafka SQL包,例如:

spark.jars.packages  org.apache.spark:spark-sql-kafka-0-10_2.11:2.2.0
以及:


什么是Spark版本和Python版本?当您使用clean会话运行此代码时,是否会遇到相同的错误?您好,spark版本是2.1,python版本是2.7。我不知道你们所说的“清理会话”是什么意思,但每次我使用spark submit在yan上启动作业时都会遇到相同的错误。我的意思是,这个错误看起来和卡夫卡无关writes@NachiketKate你能找到答案吗?我也面临同样的问题。无法写出融合的卡夫卡主题。谢谢回答。我将尝试此方法并让您知道。使用dataframe.write()我不会得到任何方法错误。看起来版本与spark、kafka、spark sql kafka不匹配。
spark sql kafka
组件必须与spark和Scala版本匹配如何只向kafka发送一列数据帧而不是整个记录?
from pyspark.sql.functions import to_json, col, struct

(df 
    .select(to_json(struct([col(c).alias(c) for c in df.columns])))
    .write
    .format("kafka") 
    .option("kafka.bootstrap.servers", botstrap_servers) 
    .option("topic", topic)
    .save())