Pyspark sc.textFile()不会完全加载文件

时间:2017-10-17 17:44:15

标签: python hadoop apache-spark pyspark cloudera

我从Cloudera quickstart docker容器上的Python Spark(v 1.6.0)开始。 我在/user/root/access_log.txt下的hdfs中添加了一个静态 .txt文件(500 mb)。

在pyspark中,我尝试使用以下python代码行加载文件:

lines = sc.textFile("hdfs://quickstart.cloudera/user/root/access_log.txt")

这给了我没有错误。但我发现文件未完全加载。 还.. ..

lines.max()

当hdfs实际上有正确的文件大小时,不会给文件的正确的最后一个元素。

这是一个记忆问题吗?我的泊坞窗设置设置为3840 MB。 我不知道如何解决这个问题。我期待着你的回答。

修改

我计算了数据集中的元素:

lines.count()

令我惊讶的是它是正确的!这应该意味着我的文件已正确加载。但问题仍然是 .max()语句没有返回正确元素的原因。

这与不同的任务有关吗?

编辑2 : .txt文件中的一些示例行

10.190.174.142 - - [03/Dec/2011:13:28:10 -0800] "GET /images/filmpics/0000/2229/GOEMON-NUKI-000163.jpg HTTP/1.1" 200 184976
10.190.174.142 - - [03/Dec/2011:13:28:11 -0800] "GET /images/filmmediablock/360/GOEMON-NUKI-000163.jpg HTTP/1.1" 200 60117
10.190.174.142 - - [03/Dec/2011:13:28:10 -0800] "GET /images/filmmediablock/360/Chacha.jpg HTTP/1.1" 200 109379
10.190.174.142 - - [03/Dec/2011:13:28:11 -0800] "GET /images/filmmediablock/360/GOEMON-NUKI-000159.jpg HTTP/1.1" 200 161657

1 个答案:

答案 0 :(得分:3)

一般来说,max不应该返回(...)最后一个元素。在某些情况下,如果日志文件使用的格式强制执行字典顺序,并且您对内容感到幸运,那么它就不会发生。由于您的数据以IP地址为前缀并使用不友好(不是例如ISO 8601)时间戳格式,因此获取最后一个元素并不是您所期望的。

找到最后一个元素的一种方法是包含索引:

from operator import itemgetter

(rdd
    .zipWithIndex()                # Add line number to get (line, no)
    .max(key=itemgetter(1))[0])    # Compare elements using index

有点不同的方法是找到每个分区的最后一个元素,然后找到最后一个元素。

from functools import reduce

rdd.mapPartitions(lambda part: reduce(lambda _, x: [x], part, [])).collect()[-1]

或者如果分区数量很大:

(rdd
    .mapPartitionsWithIndex(
        lambda i, part: reduce(lambda _, x: [(i, x)], part, []))
    .max()[1])  # Take max using tuple ordering
相关问题