Как я могу использовать SparkContext (для создания SparkSession или сессий Кассандры) на исполнителях?

Если я передам его в качестве параметра foreach или foreachPartition, то он будет иметь значение null. Должен ли я создать новый SparkContext у каждого исполнителя?

Я пытаюсь сделать следующее:

Прочитайте каталог дампа с миллионами файлов XML:

dumpFiles = Directory.listFiles(dumpDirectory)
dumpFilesRDD = sparkContext.parallize(dumpFiles, numOfSlices)
dumpFilesRDD.foreachPartition(dumpFilePath->parse(dumpFilePath))

В parse() каждый файл XML проверяется, анализируется и вставляется в несколько таблиц с использованием Spark SQL. Только допустимые файлы XML будут представлять объекты того же типа, которые могут быть сохранены. Часть данных должна быть заменена другими ключами перед вставкой в одну из таблиц.

Для этого необходимо SparkContext в функции parse, чтобы использовать sparkContext.sql().

-2
fattah.safa 27 Май 2017 в 19:15

2 ответа

Лучший ответ

Если бы я перефразировал ваш вопрос, вам нужно:

  1. Читать каталог с миллионами файлов XML
  2. Разобрать их
  3. Вставьте их в базу данных

Это типичный процесс извлечения, преобразования и загрузки (ETL), который ужасно прост в Spark SQL.

Загрузка файлов XML может быть выполнена с помощью отдельного пакета spark-xml:

spark-xml Библиотека для анализа и запроса данных XML с помощью Apache Spark, для Spark SQL и DataFrames. Структура и инструменты тестирования в основном скопированы из CSV Data Source для Spark.

Вы можете «установить» пакет, используя параметр командной строки --packages:

$SPARK_HOME/bin/spark-shell --packages com.databricks:spark-xml_2.11:0.4.1

Цитировать spark-xml API Scala (с некоторыми изменениями для использования {{X0} } вместо):

// Step 1. Loading XML files
val path = "the/path/to/millions/files/*.xml"
val spark: SparkSession = ???
val files = spark.read
  .format("com.databricks.spark.xml")
  .option("rowTag", "book")
  .load(path)

Это делает первое требование почти легким делом. Spark SQL позаботился о ваших миллионах XML-файлов.

Шаг 2 посвящен анализу строк (из файлов XML) и маркировке строк, которые будут сохранены в соответствующих таблицах.

// Step 2. Transform them (using parse)
def parse(line: String) = ???
val parseDF = files.map { line => parse(line) }

Ваша parse функция может вернуть что-то (как основной результат) и таблицу, в которую что-то должно быть сохранено.

Используя табличные маркеры , вы разделяете parseDF на кадры данных для каждой таблицы.

val table1DF = parseDF.filter($"table" === "table1")

И так далее (за столом).

// Step 3. Insert into DB    
table1DF.write.option(...).jdbc(...)

Это всего лишь набросок того, за чем вы можете действительно следовать, но это общий шаблон для подражания. Разложите ваш конвейер на усваиваемые куски и займитесь одним куском за раз.

3
Jacek Laskowski 28 Май 2017 в 19:02

Важно помнить, что в Spark мы не должны программировать с точки зрения исполнителей.

В модели программирования Spark ваша драйверная программа в основном является автономной программой, в которой определенные разделы будут автоматически преобразованы в физический план выполнения. В конечном итоге куча задач распределяется между работниками / исполнителями.

Когда вам нужно выполнить что-то для каждого раздела, вы можете использовать что-то вроде mapPartitions (). См. Spark: подключение к БД для каждого раздела Spark RDD и выполните mapPartition для получения дополнительной информации. Обратите внимание на то, как объект dbConnection заключен в тело функции.

Непонятно, что вы подразумеваете под параметром. Если это просто данные (не соединение с БД или подобное), я думаю, вам нужно использовать переменная boradcast.

2
Tharaka 27 Май 2017 в 22:01