arrays - Spark中iterable与Array的关系

标签 arrays scala apache-spark

我注意到如果我申请 mapPartitions在 RDD 上,分区获得一个可迭代对象。内mapPartitions函数,然后我调用 toArray可迭代对象的成员函数,用于将该可迭代对象转换为 Array 对象。是否调用toArray涉及复制,还是只是开始引用与数组相同的内存部分?如果确实涉及复制,有什么方法可以防止复制?

最佳答案

对您的问题的一个重要更正 - 在 mapPartitions 期间公开的分区数据结构是一个迭代器,而不是可迭代的。接口(interface)区别如下:

  • Iteratornext()hasNext() 方法,允许您访问集合中的每个元素一次。一旦调用了迭代器的 next() 方法,最后一个元素就消失了(除非您将它存储在变量中)。
  • 一个 Iterable 可以随时生成一个 Iterator。这使您可以根据需要多次访问每个元素。

  • 在实现方面,Iterator 可以流式传输数据。您实际上一次只需要在内存中拥有一个元素,该元素在调用 next() 时加载。如果您正在使用 Spark ( sc.textFile ) 从文本文件中读取数据,它会执行此操作,并且几乎不使用内存来通过分区进行简单的迭代。

    您绝对可以调用 iterator.toArray ,但您可能不想这样做。您最终将所有数据插入内存(Spark 不能一次仅加载一个元素,因为您一次要求所有元素),然后复制每条数据(对于原语,例如 Int ) 或为每条数据分配一个新的引用(对于 AnyRef ,如 Array[_] )。没有办法阻止这种复制。

    有时您想要将分区迭代器转换为数组,但这些用例很少见。由于不必要的分配和 GC,您可能会耗尽内存并大大降低应用程序的速度,因此请认真考虑是否真的需要它!

    关于arrays - Spark中iterable与Array的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41264566/

    相关文章:

    javascript - 选择数组中的项目 - Javascript - 使用 Filter 方法

    java - 按最后一个数字升序对文件数组进行排序的正确方法

    algorithm - 在 Scala 中实现成对线性距离

    scala - 在spark-shell中加载资源

    java - 初始化一个RDD为空

    ruby - 找到数组的第二个元素

    javascript - 如何将 uri 响应传递给另一个函数并获取长度?

    scala - 替代模型scala

    scala - Spark 数据帧检查点清理

    apache-spark - Spark 如何处理大于集群内存的数据