Apache Hudi Lakehouse
Обзор
- Развертывание Object Storage, Apache Spark, Hudi и Selena с помощью Docker compose
- Загрузка небольшого набора данных в Hudi с помощью Apache Spark
- Настройка Selena для доступа к Hive Metastore с использованием external catalog
- Запрос данных с помощью Selena там, где данные находятся

Помимо эффективной аналитики локальных данных, Selena может работать как вычислительный движок для анализа данных, хранящихся в озерах данных, таких как Apache Hudi, Apache Iceberg и Delta Lake. Одной из ключевых особенностей Selena является external catalog, который выступает в качестве связующего звена с внешне поддерживаемым метахранилищем. Эта функциональность предоставляет пользователям возможность беспрепятственно запрашивать внешние источники данных, устраняя необходимость в миграции данных. Таким образом, пользователи могут анализировать данные из различных систем, таких как HDFS и Amazon S3, в различных форматах файлов, таких как Parquet, ORC и CSV и т.д.
Предыдущий рисунок показывает сценарий аналитики озера данных, где Selena отвечает за вычисления и анализ данных, а озеро данных отвечает за хранение, организацию и обслуживание данных. Озера данных позволяют пользователям хранить данные в открытых форматах хранения и использовать гибкие схемы для создания отчетов на основе "единого источника истины" для различных случаев использования BI, AI, ad-hoc и отчетности. Selena полностью использует преимущества своего векторизационного движка и CBO, значительно улучшая производительность аналитики озера данных.
Предварительные требования
Репозиторий demo Selena
Клонируйте репозиторий demo Selena на ваш локальный компьютер.
Все шаги в этом руководстве будут выполняться из директории demo/documentation-samples/hudi/ в каталоге, где вы клонировали GitHub репозиторий demo.
Docker
- Настройка Docker: Для Mac следуйте шагам, описанным в Install Docker Desktop on Mac. Для выполнения Spark-SQL запросов убедитесь, что Docker выделено не менее 5 ГБ памяти и 4 процессора (см. Docker → Preferences → Advanced). В противном случае spark-SQL запросы могут быть прерваны из-за проблем с памятью.
- 20 ГБ свободного дискового пространства, выделенного для Docker
SQL клиент
Вы можете использовать SQL клиент, предоставленный в среде Docker, или использовать клиент в вашей системе. Подойдут многие клиенты, совместимые с MySQL.
Конфигурация
Перейдите в директорию demo/documentation-samples/hudi и посмотрите на файлы. Это не руководство по Hudi, поэтому не каждый конфигурационный файл будет описан; но важно, чтобы читатель знал, где искать информацию о том, как настроены компоненты. В директории hudi/ вы найдете файл docker-compose.yml, который используется для запуска и настройки сервисов в Docker. Вот список этих сервисов и краткое описание:
Сервисы Docker
| Сервис | Обязанности |
|---|---|
starrocks-fe | Управление метаданными, клиентские подключения, планы запросов и планирование |
starrocks-be | Выполнение планов запросов |
metastore_db | База данных Postgres, используемая для хранения метаданных Hive |
hive_metastore | Предоставляет Apache Hive metastore |
minio и mc | MinIO Object Storage и клиент командной строки MinIO |
spark-hudi | MinIO Object Storage |
Конфигурационные файлы
В директории hudi/conf/ вы найдете конфигурационные файлы, которые монтируются в контейнер spark-hudi.
core-site.xml
Этот файл содержит настройки, связанные с object storage. Ссылки на этот и другие элементы в разделе "Дополнительная информация" в конце этого документа.
spark-defaults.conf
Настройки для Hive, MinIO и Spark SQL.
hudi-defaults.conf
Файл по умолчанию, используемый для подавления предупреждений в spark-shell.
hadoop-metrics2-hbase.properties
Пустой файл, используемый для подавления предупреждений в spark-shell.
hadoop-metrics2-s3a-file-system.properties
Пустой файл, используемый для подавления предупреждений в spark-shell.
Запуск демонстрационного кластера
Эта демонстрационная система состоит из сервисов Selena, Hudi, MinIO и Spark. Запустите Docker compose для запуска кластера:
docker compose up --detach --wait --wait-timeout 60
[+] Running 8/8
✔ Network hudi Created 0.0s
✔ Container hudi-starrocks-fe-1 Healthy 0.1s
✔ Container hudi-minio-1 Healthy 0.1s
✔ Container hudi-metastore_db-1 Healthy 0.1s
✔ Container hudi-starrocks-be-1 Healthy 0.0s
✔ Container hudi-mc-1 Healthy 0.0s
✔ Container hudi-hive-metastore-1 Healthy 0.0s
✔ Container hudi-spark-hudi-1 Healthy 0.1s
При работе с множеством контейнеров вывод docker compose ps легче читать, если передать его через jq:
docker compose ps --format json | \
jq '{Service: .Service, State: .State, Status: .Status}'
{
"Service": "hive-metastore",
"State": "running",
"Status": "Up About a minute (healthy)"
}
{
"Service": "mc",
"State": "running",
"Status": "Up About a minute"
}
{
"Service": "metastore_db",
"State": "running",
"Status": "Up About a minute"
}
{
"Service": "minio",
"State": "running",
"Status": "Up About a minute"
}
{
"Service": "spark-hudi",
"State": "running",
"Status": "Up 33 seconds (healthy)"
}
{
"Service": "starrocks-be",
"State": "running",
"Status": "Up About a minute (healthy)"
}
{
"Service": "starrocks-fe",
"State": "running",
"Status": "Up About a minute (healthy)"
}
Настройка MinIO
При выполнении команд Spark вы установите basepath для создаваемой таблицы в URI s3a:
val basePath = "s3a://huditest/hudi_coders"
На этом шаге вы создадите bucket huditest в MinIO. Консоль MinIO работает на порту 9000.
Аутентификация в MinIO
Откройте браузер по адресу http://localhost:9000/ и выполните аутентификацию. Имя пользователя и пароль указаны в docker-compose.yml; это admin и password.
Создание bucket
В левой навигации выберите Buckets, а затем Create Bucket +. Назовите bucket huditest и выберите Create Bucket

Создание и заполнение таблицы, затем синхронизация с Hive
Выполняйте эту команду и любые другие команды docker compose из директории, содержащей файл docker-compose.yml.
Откройте spark-shell в сервисе spark-hudi
docker compose exec spark-hudi spark-shell
При запуске spark-shell будут предупреждения о незаконном рефлексивном доступе. Вы можете игнорировать эти предупреждения.
Выполните эти команды в приглашении scala> для:
- Настройки этой сессии Spark для загрузки, обработки и записи данных
- Создания dataframe и записи его в таблицу Hudi
- Синхронизации с Hive Metastore
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
import org.apache.spark.sql.Row
import org.apache.spark.sql.SaveMode._
import org.apache.hudi.DataSourceReadOptions._
import org.apache.hudi.DataSourceWriteOptions._
import org.apache.hudi.config.HoodieWriteConfig._
import scala.collection.JavaConversions._
val schema = StructType( Array(
StructField("language", StringType, true),
StructField("users", StringType, true),
StructField("id", StringType, true)
))
val rowData= Seq(Row("Java", "20000", "a"),
Row("Python", "100000", "b"),
Row("Scala", "3000", "c"))
val df = spark.createDataFrame(rowData,schema)
val databaseName = "hudi_sample"
val tableName = "hudi_coders_hive"
val basePath = "s3a://huditest/hudi_coders"
df.write.format("hudi").
option(org.apache.hudi.config.HoodieWriteConfig.TABLE_NAME, tableName).
option(RECORDKEY_FIELD_OPT_KEY, "id").
option(PARTITIONPATH_FIELD_OPT_KEY, "language").
option(PRECOMBINE_FIELD_OPT_KEY, "users").
option("hoodie.datasource.write.hive_style_partitioning", "true").
option("hoodie.datasource.hive_sync.enable", "true").
option("hoodie.datasource.hive_sync.mode", "hms").
option("hoodie.datasource.hive_sync.database", databaseName).
option("hoodie.datasource.hive_sync.table", tableName).
option("hoodie.datasource.hive_sync.partition_fields", "language").
option("hoodie.datasource.hive_sync.partition_extractor_class", "org.apache.hudi.hive.MultiPartKeysValueExtractor").
option("hoodie.datasource.hive_sync.metastore.uris", "thrift://hive-metastore:9083").
mode(Overwrite).
save(basePath)
System.exit(0)
Вы увидите предупреждение:
WARN
org.apache.hudi.metadata.HoodieBackedTableMetadata -
Metadata table was not found at path
s3a://huditest/hudi_coders/.hoodie/metadata
Это можно игнорировать, файл будет создан автоматически во время этой сессии spark-shell.
Также будет предупреждение:
78184 [main] WARN org.apache.hadoop.fs.s3a.S3ABlockOutputStream -
Application invoked the Syncable API against stream writing to
hudi_coders/.hoodie/metadata/files/.files-0000_00000000000000.log.1_0-0-0.
This is unsupported
Это предупреждение информирует вас о том, что синхронизация лог-файла, открытого для записи, не поддерживается при использовании object storage. Файл будет синхронизирован только после его закрытия. См. Stack Overflow.
Последняя команда в приведенной выше сессии spark-shell должна выйти из контейнера, если этого не произошло, нажмите enter и он выйдет.
Настройка Selena
Подключение к Selena
Подключитесь к Selena с помощью предоставленного MySQL клиента сервиса starrocks-fe, или испо льзуйте ваш любимый SQL клиент и настройте его для подключения по протоколу MySQL на localhost:9030.
docker compose exec starrocks-fe \
mysql -P 9030 -h 127.0.0.1 -u root --prompt="StarRocks > "
Создание связи между Selena и Hudi
В конце этого руководства есть ссылка с дополнительной информацией об external catalog. External catalog, созданный на этом шаге, действует как связь с Hive Metastore (HMS), работающим в Docker.
CREATE EXTERNAL CATALOG hudi_catalog_hms
PROPERTIES
(
"type" = "hudi",
"hive.metastore.type" = "hive",
"hive.metastore.uris" = "thrift://hive-metastore:9083",
"aws.s3.use_instance_profile" = "false",
"aws.s3.access_key" = "admin",
"aws.s3.secret_key" = "password",
"aws.s3.enable_ssl" = "false",
"aws.s3.enable_path_style_access" = "true",
"aws.s3.endpoint" = "http://minio:9000"
);
Query OK, 0 rows affected (0.59 sec)
Использование нового catalog
SET CATALOG hudi_catalog_hms;
Query OK, 0 rows affected (0.01 sec)