【问题标题】:SparkContext inside map地图内的 SparkContext
【发布时间】:2015-04-26 16:46:43
【问题描述】:

我有很大的文件夹列表(10.000 个文件夹),里面有 .gz 文件,并尝试在每个文件夹的基础上做一些事情,例如将每个文件拆分为较小的部分。

为此,我决定:

  1. 以 Array[String] 形式获取文件夹路径列表
  2. 将这个相当大的列表并行到节点
  3. foldersRDD.foreach(folderName => .... sc.textFile(folderName) ....

它在本地工作,但在集群上会导致 NullPointerException(我猜,SparkContext 对于每个执行程序节点都是空的,我们根本不能在节点的函数代码中使用它)。
我如何重做此示例以确保 1-folder-per-single-worker 执行模式或其他避免/最小化任何繁重操作(如随机播放)的方式?

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    您可以将您的解决方案与命令wholeTextFiles() 结合使用。这只是一个技巧,但它可能对你有好处。

    根据official spark documentation,命令wholeTextFiles() 允许您读取包含多个小文本文件的目录,并将每个文件作为filename/content 对返回。这与textFile() 形成对比,textFile() 在每个文件中每行返回一条记录。

    您可以从文件夹路径的原始数组开始,创建一组 key/value RDD-s,每个 RDD-s 代表 filename/content 数据中整个文件夹的名称和内容格式。

    考虑以下起始场景:

    Folder 1 (location > hdfs:\\Folder1)
        - File01 (location > hdfs:\\Folder1\File01) > Hello this is the content of file 01
        - File02 (location > hdfs:\\Folder1\File02) > Hello this is the content of file 02
    
    Folder 2 (location > hdfs:\\Folder1)
        - File03 (location > hdfs:\\Folder2\File03) > Hello this is the content of file 03
        - File04 (location > hdfs:\\Folder2\File04) > Hello this is the content of file 04
    

    假设你有一个 arraystrings 组成,其中包含每个文件夹的名称,看起来像

    DirArray[0]: "hdfs:\\Folder1"
    DirArray[1]: "hdfs:\\Folder2"
    

    下一步是为每个文件夹创建一个 RDD。每个 RDD 将以filename/content 格式表示整个文件名列表及其内容。为此,您可以遍历 path 数组并为每个元素调用命令 wholeTextFiles()。它将包括以下内容:

    For each element in DirArray > wholeTextFiles("hdfs:\\FolderN")
    

    每个生成的 RDD 如下所示:

    firstFolderRDD (key/value):
        - "hdfs:\\Folder1\File01" > "Hello this is the content of file 01
        - "hdfs:\\Folder1\File02" > "Hello this is the content of file 02
    

    此时,将有两种选择:

    a) 将每个 RDD 存储在 类数组 结构中,稍后计算其元素

    b) 在每个 RDD 生成时计算它们的元素(在前面的 for each 部分中)。

    需要注意的是,这种方法只推荐用于一组小文件,主要是因为新创建的 RDD-s 的每一行都将包含它所代表的文件的全部内容。

    【讨论】:

      【解决方案2】:

      在您的示例中,foreach 中的代码被序列化并传输给工作人员。你是对的,他们没有 sparkContext。

      我的建议:使用foldersList 而不是 RDD,并祈祷您的 RDD 是在数据所在的同一个工作人员上创建的。在理想情况下,您有小文件(在许多节点上没有被 hdfs 划分)并且每个工作人员都有足够的内存 - 不会有洗牌。在实际情况下,yarn 将为您降低成本 - 这是他的工作,而不是您的工作。

      附:可能有一些技巧,其他更有经验的人可以更好地回答你。我只是推荐在幕后信任 hadoop 魔法,并把时间花在算法的实际实现上。祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        • 2022-01-25
        相关资源
        最近更新 更多