Apache spark 如何构建一个包含两个kafka流的数据帧;钥匙;列和剩余列是最新的值
我的Spark 2.4.x(pyspark)应用程序需要:Apache spark 如何构建一个包含两个kafka流的数据帧;钥匙;列和剩余列是最新的值,apache-spark,pyspark,spark-streaming,spark-structured-streaming,spark-streaming-kafka,Apache Spark,Pyspark,Spark Streaming,Spark Structured Streaming,Spark Streaming Kafka,我的Spark 2.4.x(pyspark)应用程序需要: 输入是两个卡夫卡主题,输出是一个卡夫卡主题 “流表”在哪里 有一个逻辑键和 其余列应为任一流的最新值 亚秒延迟。测试表明,当水印不存在时,这是可以实现的 用过 这似乎是一件基本的事情,但它并不完全适合我 例子: 注意:在下面的示例中,T1、T2和T2时间点可以相隔秒/分钟/小时 T1)在时间T1 KafkaPriceTopic获取1条消息负载(我们称之为P1): {“SecurityCol”:“Sec1”、“priceqnocol
- 有一个逻辑键和
- 其余列应为任一流的最新值李>
水印不存在时,这是可以实现的
用过
例子: 注意:在下面的示例中,T1、T2和T2时间点可以相隔秒/分钟/小时 T1)在时间T1 KafkaPriceTopic获取1条消息负载(我们称之为P1):
{“SecurityCol”:“Sec1”、“priceqnocol”:“1”、“PriceCol”:“101.5”}
KafkaVolumeTopic1带有有效负载的消息(我们称之为V1):{“SecurityCol”:“Sec1”、“VolumeSeqNoCol”:“1”、“VolumeCol”:“50”}
我希望得到一个结果数据帧
,如下所示:
+-----------+--------+---------+-------------+--------------+
|SecurityCol|PriceCol|VolumeCol|PriceSeqNoCol|VolumeSeqNoCol|
+-----------+--------+---------+-------------+--------------+
|Sec1 |101.5 |50 |1 |1 |
+-----------+--------+---------+-------------+--------------+
T2)卡夫卡普里塞托普1信息(P2):{“SecurityCol”:“Sec1”、“PriceSeqNoCol”:“2”、“PriceCol”:“101.6”}
结果数据帧
+-----------+--------+---------+-------------+--------------+
|SecurityCol|PriceCol|VolumeCol|PriceSeqNoCol|VolumeSeqNoCol|
+-----------+--------+---------+-------------+--------------+
|Sec1 |101.6 |50 |2 |1 |
+-----------+--------+---------+-------------+--------------+
+-----------+--------+---------+-------------+--------------+
|SecurityCol|PriceCol|VolumeCol|PriceSeqNoCol|VolumeSeqNoCol|
+-----------+--------+---------+-------------+--------------+
|Sec1 |101.6 |60 |2 |2 |
+-----------+--------+---------+-------------+--------------+
注意:P1不再相关
T3)卡夫卡沃卢梅托皮克1信息V2:{“SecurityCol”:“Sec1”、“VolumeSeqNoCol”:“2”、“VolumeCol”:“60”}
结果数据帧
+-----------+--------+---------+-------------+--------------+
|SecurityCol|PriceCol|VolumeCol|PriceSeqNoCol|VolumeSeqNoCol|
+-----------+--------+---------+-------------+--------------+
|Sec1 |101.6 |50 |2 |1 |
+-----------+--------+---------+-------------+--------------+
+-----------+--------+---------+-------------+--------------+
|SecurityCol|PriceCol|VolumeCol|PriceSeqNoCol|VolumeSeqNoCol|
+-----------+--------+---------+-------------+--------------+
|Sec1 |101.6 |60 |2 |2 |
+-----------+--------+---------+-------------+--------------+
注意:P1和V1不再相关
什么有效
get_json\u object
暂时),
连接两个主题的流李>
不过。这将产生(不带水印
)一个数据帧
,它具有所有
Sec1收到的价格和数量,而不仅仅是最新的价格和数量李>
所以后面是一个groupBy(…).agg(last(…),…)
。但我坚持下去了
仅获取一行最新值
dfKafka1=spark.readStream.format(“kafka”)#剩余选项等
.load()
.选择(…)#将字段提取为列“
dfKafka2=spark.readStream.format(“kafka”)#剩余选项等
.load()
.选择(…)#将字段提取为列“
dfResult=dfKafka1.join(dfKafka2,“SecurityCol”)
#结构化流媒体还不允许在加入后使用groupBy,因此请编写中间kafka主题
dfResult.writestream.format(“卡夫卡”)#剩余选项
.trigger(processingTime=“1秒”)
.start()
#加载中间卡夫卡主题
dfKafkaResult=spark.readStream.format(“kafka”)#剩余选项
.load()
.为cols选择(…)#获取json_对象
.groupBy(“SecurityCol”)#定义agg cols的“密钥”
.agg(最后一列(“价格列”),#每列的最新值
最后(“PriceSexNocol”),
最后(“VolumeCol”),
最后一个(“卷号”))
问题
然而,最后的agg
和last()
并没有始终如一地发挥作用
当KafkaVolumeTopic收到一条新消息时,结果可能与
卡夫卡普里塞托普传来的一条老消息
此外,orderBy
/sort不能在没有聚合的流上使用
限制
在加入之前,我不能groupBy
,因为这需要带有水印
,我想我的应用程序不能使用水印
。理论基础:
- 应用程序应该能够在一天中的任何时间加入给定SecurityCol的两个主题。
- 如果PriceTopic在上午9点收到消息,VolumeTopic在上午10点收到消息
- 我希望这两个人能一起出席
- 水印限制以
append
模式发送数据的时间。所以不能在这里使用水印,因为时间范围是一整天
有什么想法吗