我正在用Kafka,Spark和jupyter笔记本进行概念验证,而我遇到一个奇怪的问题。我正在尝试从kafka到pyspark读取Avro记录。我正在使用融合式架构注册表来获取用于反序列化avro消息的架构。 将Spark数据框中的Avro消息反序列化后,结果列为空,没有任何错误。该列应包含数据,因为当转换为字符串时,某些avro字段是可读的。
我也曾尝试在Scala的spark-shell上执行此操作(没有jupyter) 我已经尝试了基于docker的spark以及独立安装的spark
我遵循了这个SO主题,以获取from_avro和to_avro函数: Pyspark 2.4.0, read avro from kafka with read stream - Python
struct
值列的内容为空。我预计由于解码失败而出现错误,或者数据在那里。有谁知道这可能是什么原因或如何调试?
jars = ["kafka-clients-2.0.0.jar", "spark-avro_2.11-2.4.3.jar", "spark-
sql-kafka-0-10_2.11-2.4.3.jar"]
jar_paths = ",".join(["/home/jovyan/work/jars/{}".format(jar) for jar in
jars])
conf = SparkConf()
conf.set("spark.jars", jar_paths)
spark_session = SparkSession \
.builder \
.config(conf=conf)\
.appName("TestStream") \
.getOrCreate()
def from_avro(col, jsonFormatSchema):
sc = SparkContext._active_spark_context
avro = sc._jvm.org.apache.spark.sql.avro
f = getattr(getattr(avro, "package$"), "MODULE$").from_avro
return Column(f(_to_java_column(col), jsonFormatSchema))
def to_avro(col):
sc = SparkContext._active_spark_context
avro = sc._jvm.org.apache.spark.sql.avro
f = getattr(getattr(avro, "package$"), "MODULE$").to_avro
return Column(f(_to_java_column(col)))
schema_registry_url = "http://schema-registry.org"
transaction_schema_name = "Transaction"
transaction_schema = requests.get("
{}/subjects/{}/versions/latest/schema".format(schema_registry_url,
transaction_schema_name)).text
raw_df = spark_session.read.format("kafka") \
# SNIP
.option("subscribe", "transaction") \
.option("startingOffsets", "earliest").load()
raw_df = raw_df.limit(1000).cache()
extract_df = raw_df.select(
raw_df["key"].cast("String"),
from_avro(raw_df["value"], transaction_schema).alias("value")
)
# This shows data and fields
raw_df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)").show(3, truncate=False)
extract_df.show()
答案 0 :(得分:2)
您必须手动反序列化数据。撰写本文时,PySpark尚未正式支持Confluent模式注册表。您需要使用Confluent提供的KafkaAvroDeSerializer或第三方Spark avro库ABRiS。
ABRiS:https://github.com/AbsaOSS/ABRiS#using-abris-with-python-and-pyspark
KafkaAvroDeSerializer:Integrating Spark Structured Streaming with the Confluent Schema Registry
原因:Confluent在Avro数据后添加了5个额外的字节,其中1个用于魔术字节,4个用于模式ID,而不是典型的avro格式,即Avro数据。因此,您需要手动反序列化。
(对不起,我无法发表评论。)