有一个火花流式传输作业一直在运行,计算流中的单词,只计算和返回给定词汇表中的单词。
但是,这个词汇不是固定的,而是词汇表存储在NSManagedObjects
中,并且可以随时间变化。以下是这项工作的天真实施:
redis
我认为我的实现性能很差,因为sc = SparkContext(appName="WordCount")
ssc = StreamingContext(sc, 10) # batch interval is 10s
def check_if_in_vocab(word):
vocab = redis_client.smembers() # get all vocabulary from redis
return word in vocab
lines = ssc.socketTextStream(host_ip, port) # read data stream from the socket
words = lines.flatMap(lambda line: line.split(" "))\
.filter(check_if_in_vocab)\ # ANY BETTER SOLUTION HERE???
.map(lambda word: (word, 1)) # create (word, count) pair
counts = words.reduceByKey(lambda x,y: x+y)
counts.pprint()
转换为流中的每个元素从redis中提取词汇表,这太费时了。
有更好的解决方案吗?
后续
好的,在上面的问题中,由于词汇表可能随时改变,所以我需要经常检查filter(check_if_in_vocabulary)
,现在假设词汇表每60秒或1h只更改一次,是否更容易改进上述词汇码?
答案 0 :(得分:0)
我从未在Python中使用Spark,但如果这是Scala实现,我会通过在mapPartitions
调用中进行Redis调用来寻求改进。在mapPartitions
内,我将与客户端建立连接,获取vocab
,使用内存中vocab
来过滤可迭代,然后关闭连接。
也许你可以做一些与Python API类似的事情。