根据时间戳过滤Spark中的大型Kafka DataStream

时间:2019-12-24 21:43:41

标签: mongodb apache-spark pyspark apache-kafka pyspark-sql

在AWS的Kafka代理服务器上,我有大约3600条来自120种不同设备的警报作为Kafka消息发出。这些警报是来自各种本地摄像机的基于时间戳的活动对象检测源。一台摄像机每秒可以发送30条Kafka消息。

基本流程如下:

设备---> Kafka服务---> Spark ----> MongoDB

示例警报流如下所示:

{ "message-id":"", object_id:10, sensor_id:"Splitter Bay Camera 1", timestamp":"2019-12-24T00:00:00.000Z }
{ "message-id":"", object_id:10, sensor_id:"Splitter Bay Camera 1", timestamp":"2019-12-24T00:00:00.010Z }
{ "message-id":"", object_id:10, sensor_id:"Splitter Bay Camera 1", timestamp":"2019-12-24T00:00:00.014Z }
{ "message-id":"", object_id:12, sensor_id:"Splitter Bay Camera 1", timestamp":"2019-12-24T00:00:17.599Z }

我希望每3秒仅将每台设备的最新警报保存到mongodb中,这样我就不会因大量的kafka消息转储而淹没数据库空间。为此,我了解我需要在时间戳上对传入流进行排序并将其保存到mongodb。到目前为止,我可以使用以下代码将所有流保存到mongodb

from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils
import json
import global_vals
from mongo_utils import mongo_utils
import unicodedata

def insert_row(x):
    if x is None or len(x)<1:
        return

    str_jsn = json.dumps(x)    
    mongo_utils.insert_data(str_jsn)

sc=SparkContext(master='local[*]',appName='test')
ssc=StreamingContext(sc,batchDuration=global_vals.data_produce_duration)
brokers='ec2-some-ipaddress.compute-1.amazonaws.com:9092'
topic=global_vals.kafka_topic
kvs=KafkaUtils.createDirectStream(ssc,[topic],kafkaParams={"metadata.broker.list":brokers})
#kvs.pprint()
lines=kvs.map(lambda x: json.loads(x[1]))
lines.foreachRDD(lambda rdd:rdd.foreach(insert_row))

ssc.start()
ssc.awaitTermination()

我无法弄清楚该如何处理。我是否应该执行另一种工作,每3秒不断轮询Kafka以处理最新警报,然后将其保存到数据库中,或者可以直接在Spark中完成?

0 个答案:

没有答案