Spark流式传输和在流式词典上执行操作

时间:2016-07-01 16:25:47

标签: python apache-spark spark-streaming

奇怪的是,我想要查看我正在流式传输的一系列词典中的k,v对的数量,但是我发现我似乎无法做到这一点。

lines = ssc.socketTextStream("127.0.0.1", 5006) 
json_format = lines.flatMap(lambda recieved: json.loads(recieved))
dict_format = json_format.flatMap(lambda x : len(x) ).reduce(lambda a, b: a+b)

例如,我收到以下错误:

File "/home/xx/spark-1.6.1/python/pyspark/rdd.py", line 1776, in combineLocally
    merger.mergeValues(iterator)
  File "/home/xx/spark-1.6.1/python/pyspark/shuffle.py", line 236, in mergeValues
    for k, v in iterator:
TypeError: 'int' object is not iterable

我可以假设我们有一系列词典 - json.loads()没有失败,但我似乎无法采用这个简单的长度。

1 个答案:

答案 0 :(得分:0)

Spark期望提供给flatMap的函数将为它从源RDD / DStream处理的每个元素返回一个可遍历/可迭代的结果(例如列表)。可能会发生TypeError: 'int' object is not iterable错误,因为Spark正在尝试迭代从您传递给flatMap的lambda之一返回的非可迭代值。

第二次flatMap调用(json_format.flatMap)肯定是个问题,因为len(...)将始终返回int,因此它最有可能是罪魁祸首。由于看起来意图是对int执行1对1转换(即长度),因此您应该能够通过将flatMap替换为{{3}来解决该问题。相反。

第一次 flatMap调用是否有效取决于输入。如果您确定源文件中的每一行都是一个将解析为JSON数组的字符串,那么它应该按预期工作。但是,如果文件中任何行的JSON解析将生成类型其他而不是数组,则解析函数将向flatMap发送不可迭代的结果,并且作业将失败并且与您目前看到的错误类似的错误:

>>> type(json.loads('{"asdf": "qwerty"}'))
<class 'dict'>
>>> type(json.loads('[{"asdf": "qwerty"}, [1,2,3]]'))
<class 'list'>
>>> type(json.loads('3'))
<class 'int'>