【问题标题】:Spark: Text file to RDD[Byte]Spark:文本文件到 RDD [字节]
【发布时间】:2018-06-20 18:03:41
【问题描述】:

我需要将一个文本文件加载到 RDD 中,以便我可以在其中包含的数据上运行任务。 Driver 程序是用 Scala 编写的,将在每个任务中执行的代码可作为通过 JNI 访问的本机动态库使用。

目前,我正在以这种方式创建 RDD:

val rddFile : RDD[String] = sc.textFile(path);

我有任务的 C 本机代码,尽管它对真实文件使用字节级操作,即 fgetc()。我正在尝试模拟相同类型的操作(以尽量减少代码重构),但避免将要由所述本机库处理的数据片段写入磁盘,这会影响性能。

这是本机函数的定义以及我如何调用它:

natFunction(data : Array[String])
rddFile.glom().foreach(elem=>natFunction(elem))

但是,调用 textFile() 生成的 RDD 包含 String 对象,需要在 JNI 的本机端将其转换为有效的 C 字符串。我相信应用于文件每一行的上述转换对性能的影响可能很大,但仍小于对文件进行操作。

我还认为更兼容的类型是 RDD[Byte],这样我就可以发送到本机端 Arrays of Bytes,它可以以更直接的方式转换为 C 字符串。

这些假设是真的吗? 如果是这样,将文本文件加载为 RDD[Byte] 的有效方法是什么?

欢迎任何其他解决此问题的建议。

【问题讨论】:

    标签: scala apache-spark java-native-interface byte rdd


    【解决方案1】:

    您可以通过执行rdd.flatMap(s => s.getBytes)RDD[String] 获得RDD[Byte],但请注意 - String 很可能每个字符有 2 个字节(我猜这取决于区域设置)。

    此外,当您拥有 RDD[Byte] 时,您将需要调用,例如,mapPartitions 将您的数据作为Array[Byte] 提供给您的 C 代码。在这种情况下,您将有相当大的数组传递给您的 C 代码,但对于每个分区,C 应用程序只会被调用一次。另一种方法是使用rdd.map(s => s.getBytes),在这种情况下您将拥有RDD[Array[Byte]],因此每个分区将运行多个C 应用程序。

    我认为您可以尝试使用pipe() API 来启动您的 C 代码并将 RDD 元素通过管道传输到您的 C 代码并获取您的 C 应用程序的输出以供进一步处理。

    【讨论】:

    • 很好的答案,谢谢。顺便说一句,rdd.map(s=>s.getBytes) 不会导致 RDD[Array[Byte]] intsead 吗?
    猜你喜欢
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 2017-03-06
    • 2018-12-07
    • 2015-09-23
    相关资源
    最近更新 更多