От Derby к Hive: хранилище метаданных для Apache Spark

Автор Категория , ,
От Derby к Hive: хранилище метаданных для Apache Spark

Сегодня заглянем под капот Apache Spark и разберем, для чего этому популярному вычислительному движку база метаданных, как ее назначить и что не так с хранилищем данных по умолчанию. Зачем уходить от Apache Derby к Hive и как это сделать: краткий ликбез с примерами для обучения дата-инженеров и разработчиков распределенных приложений.

Зачем Apache Spark хранить данные и где это делается?

При том, что Apache Spark является вычислительным движком, т.е. средством аналитики больших данных, а не их хранения, и выполняет операции MapReduce в памяти, в отличие от классического Hadoop, здесь все же не обойтись без базы данных. Аналогично инструментам SQL-on-Hadoop, таким как Hive или Presto, Spark использует хранилище метаданных, т.е. реляционную СУБД для управления метаданными постоянных реляционных объектов (баз данных, таблиц, столбцов, разделов) для быстрого доступа. Кроме того, в этом хранилище, как в каталоге хранятся таблицы Spark SQL. Проверить, какое хранилище метаданных используется, поможет команда println(spark.sharedState.externalCatalog.unwrapped).

Spark SQL по умолчанию использует хранилище метаданных в памяти, развернутое с базой данных Apache Derby – реляционную СУБД, ранее известную как IBM Cloudscape. Написанная на языке программирования Java, Apache Derby предназначена для встраивания в Java-приложения или обработки транзакций в реальном времени.

При использовании Apache Derby в качестве хранилища метаданных ответом на команду println(spark.sharedState.externalCatalog.unwrapped) будет res: org.apache.spark.sql.catalyst.catalog.InMemoryCatalog.

Впрочем, несмотря на позиционирование в качестве встраиваемой СУБД, Derby работает не слишком быстро. Кроме того, эта реляционная СУБД не поддерживает управление конкурентным доступом с помощью многоверсионности (MVCC). Поэтому в реальных проектах использовать хранилище метаданных Apache Spark по умолчанию не рекомендуется из-за ограничения одновременного использования только одного активного SparkSession.

Поэтому на практике для реальных проектов в качестве хранилища метаданных для Apache Spark чаще всего применяется Hive Metastore.

Чтобы включить Hive Metastore, нужно добавить API-метод enableHiveSupport() при создании объекта SparkSession, который по умолчанию развертывается с базой данных Apache Derby. Благодаря этому в результате команды println(spark.sharedState.externalCatalog.unwrapped) ответ будет следующим: res: org.apache.spark.sql.hive.HiveExternalCatalog.

HiveExternalCatalog использует каталог spark.sql.warehouse.dir в качестве места для сохранения баз данных и таблиц. Реализация каталога управляется spark.sql.catalogImplementation и может принимать одно из двух возможных значений: hive и in-memory.

Датафреймы также можно сохранить как постоянные таблицы в хранилище метаданных Hive с помощью команды saveAsTable. В отличие от команды createOrReplaceTempView, saveAsTable материализует содержимое датафрейма и создает указатель на данные в хранилище метаданных Hive. Постоянные таблицы будут по-прежнему существовать даже после перезапуска Spark-приложения, если поддерживается подключение к тому же хранилищу метаданных. Датафрейм для постоянной таблицы можно создать, вызвав метод table() в SparkSession с именем таблицы.

Spark SQL по умолчанию использует каталог в памяти (не Hive), если не используется spark-shell.

Примечательно, что даже при отсутствии установки Hive в Spark-кластере, его хранилище метаданных можно использовать в распределенном движке. Если в конфигурационном файле hive-site.xml для Spark не настроен Hive, фреймворк автоматически создает метахранилище (metastore_db) в текущем каталоге, развернутом с помощью Apache Derby по умолчанию. Также будет создан каталог spark.sql.warehouse.dir, настроенный для хранения таблиц Spark, которые по умолчанию относятся к каталогу spark-warehouse в текущем каталоге, где запущено распределенное приложение. При этом пользователю, который запускает это распределенное Spark-приложение, потребуются права на запись в эту директорию.

Преимущества Hive Metastore для Delta Lake

При интеграции хранилища метаданных Hive с дельта-таблицей, оно будет хранить имя таблицы, ее формат и местоположение. В случае хзранения датафрейма в виде таблицы, с помощью хранилища метаданных для чтения этой дельта-таблицы достаточно указать только ее имя, без необходимости задавать полный путь и тип хранилища, такой как Hadoop HDFS или AWS S3.В частности, с метахранилищем это может выглядеть так: val df = spark.table(“dbName.tableName”).

Без метахранилища необходимо указать полный путь:

spark.read.format(“delta”).load(“gs://complete_path”)
или
spark.read.delta(“gs://complete_path”)

Чтобы включить его, нужно добавить следующую конфигурацию при создании объекта Spark Session: .config(“spark.sql.catalog.spark_catalog”, “org.apache.spark.sql.delta.catalog.DeltaCatalog”).

Узнайте больше про практическое использование Apache Spark и Hive для задач дата-инженерии, разработки распределенных приложений и аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Источники

  1. https://medium.com/@sarfarazhussain211/metastore-in-apache-spark-9286097180a4
  2. https://ru.bmstu.wiki/Apache_Derby