Как создать Spark RDD из итератора?

Чтобы было ясно, я не ищу RDD из массива/списка, например

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); // sample
JavaRDD<Integer> rdd = new JavaSparkContext().parallelize(list);

Как я могу создать искровое RDD из итератора java без полной буферизации в памяти?

Iterator<Integer> iterator = Arrays.asList(1, 2, 3, 4).iterator(); //sample iterator for illustration
JavaRDD<Integer> rdd = new JavaSparkContext().what("?", iterator); //the Question

Дополнительный вопрос:

Является ли требование, чтобы источник мог быть повторно читаемым (или способным читать много раз), чтобы предложить устойчивость для RDD? Другими словами, поскольку итераторы в принципе читаются один раз, возможно ли даже создать Resilient Distributed Datasets (RDD) из итераторов?

Ответ 1

Как сказал кто-то другой, вы можете сделать что-то с искровым потоком, но что касается чистой искры, вы не можете, и причина в том, что то, что вы просите, идет против искровой модели. Позволь мне объяснить. Чтобы распределить и распараллелить работу, искра должна разделить ее на куски. При чтении из HDFS это "chunking" выполняется для Spark с помощью HDFS, поскольку файлы HDFS организованы в виде блоков. Обычно Spark генерирует одну задачу на каждый блок. Теперь итераторы обеспечивают последовательный доступ к вашим данным, поэтому невозможно заставить искру организовать его в кусках, не читая все это в памяти.

Возможно, будет возможно создать RDD, который имеет один итерабельный раздел, но даже тогда нельзя сказать, может ли реализация Iterable быть отправлена ​​рабочим. При использовании sc.parallelize() искра создает разделы, которые реализуют serializable, поэтому каждый раздел может быть отправлен другому работнику. Итерируемый может быть через сетевое соединение или файл в локальной FS, поэтому они не могут быть отправлены рабочим, если они не буферизованы в памяти.