我有一个test()函数,该函数返回一个元组列表,最终目标是在文件中打印出称为“ test”的元组内容。
[('something',1),(“ test”,['line1', 'line2','line3']),('somethingelse',3)]
logs = sc.textFile("s3://my-bucket/file.txt")
rdd = logs.mapPartitions(lambda x: test()).reduceByKey(lambda a, b: a + b)).map(lambda (a, b): b if a == "test" else "").flatMap(lambda x: x)
rdd.collect()
['line1','line2','line3','line1','line2','line3']
我正在尝试将此RDD的所有元素写入文件中
rdd.saveAsTextFile("s3://bucket/key/)
它可以正常工作,并且sparks创建了许多零件文件(精确到215个文件),但它们都是空的,除了1.2Gb中的1个具有所有数据之外
line1
line2
line3
line1
line2
line3
这是正常行为吗?我以为Spark会并行处理写入操作,每个工作人员都会得到一个分区?为什么只将数据写入1个文件?
我有rdd.getNumPartitions()
的支票,它显示215。
答案 0 :(得分:3)
这是正常行为吗?
是的。这是正常现象。您的示例数据仅返回一个有意义的键-"test"
。您reduceByKey
将此键的所有值都洗牌到了一个分区。其余的值无关紧要。
最后两个转换
map(lambda (a, b): b if a == "test" else "").flatMap(lambda x: x)\
为了清楚起见,可以将其重写为:
filter(map(lambda (a, b): a == "test").values().flatMap(lambda x: x)
换句话说,您的代码仅使用"test"
键保留值,并且这些值已经在单个分区上。
实际上没有意义的部分是按键分组。你也可以
logs.mapPartitions(lambda x: test()).filter(map(lambda (a, b): a == "test")
这将使数据保持副作用。