Перейти к содержимому
Последнее обновление

Образ «всё в одном»: один контейнер, многоузловые кластеры и кластеры с разделением вычислений и хранения

Официальный образ Apache Doris «всё в одном», apache/doris:all-in-one-<version>, содержит выпущенные версии FE, BE и Meta Service; переменная окружения DORIS_ROLE определяет, что контейнер запускает при старте. Один и тот же образ используется в трёх сценариях:

РежимКак запуститьДля чего предназначен
Один контейнер
1 FE + 1 BE в одном контейнере, готовность примерно через 20 с
docker run apache/doris:all-in-one-4.1.3Тестовое окружение e2e / CI для проектов экосистемы, таких как коннекторы, SDK и инструменты интеграции данных: настоящий экземпляр Doris вместо имитации
Многоузловой кластер
3 FE + 3 BE, отдельный контейнер для каждого узла, готовность примерно через 35 с
docker compose -f multi-node.yml up --waitЛокальная проверка сценариев, которые нельзя воспроизвести в одном контейнере: выбор ведущего FE и переключение при отказе, три реплики, балансировка, вывод узлов из эксплуатации
Кластер с разделением вычислений и хранения
FoundationDB + Meta Service + Recycler + MinIO + от 1 до 3 FE + 3 BE в 2 вычислительных группах, готовность примерно через 50 с
docker compose -f cloud.yml up --waitЛокальная разработка функций и демонстрация режима с разделением вычислений и хранения: вычислительные группы, storage vault, переключение FE при отказе в облачном режиме без внешних облачных ресурсов

Режим с одним контейнером предназначен для CI и не требует ничего, кроме docker run. Два файла Compose находятся в каталоге docker/runtime/all-in-one/4.1/compose/ основного репозитория Doris и предназначены для локальной разработки функций и демонстраций. Во всех трёх режимах есть проверка состояния: healthy означает, что кластер сформирован, поэтому зависимым процессам не нужно опрашивать состояние или вызывать sleep.

Примечание

Все три режима предназначены для тестирования и разработки, а не для эксплуатации в рабочей среде: объём памяти уменьшен с учётом ресурсов исполнителей CI и рабочих станций, режим с одним контейнером использует одну реплику, а по умолчанию данные нигде не сохраняются. Многоузловой кластер и кластер с разделением вычислений и хранения также не заменяют конвейеры регрессионного тестирования; наборам тестов docker() из regression-test/suites/cloud_p0 по-прежнему нужен doris-compose.

Обзор образа​

Теги образов имеют вид apache/doris:all-in-one-<version>, например apache/doris:all-in-one-4.1.3. Во всех примерах ниже используется версия 4.1.3; замените её нужной вам версией. Доступные теги перечислены в репозитории apache/doris на Docker Hub.

Образ собирается из официальных образов apache/doris:fe-<version>, be-<version> и ms-<version>, поэтому внутри запускаются именно выпущенные артефакты. Для уменьшения размера выполняются только две операции: отладочная информация удаляется из doris_be, а также из компонентов Meta Service doris_cloud и libfdb_c.so (таблица .symtab сохраняется, поэтому в трассировках стека при сбоях по-прежнему определяются имена функций), и удаляются каталоги JNI-сканеров, которые не нужны данному тегу.

Два тега: базовый и -full​

ТегВозможностиРазмер образа (4.1.3, без сжатия)
apache/doris:all-in-one-<version>Внутренние таблицы, Hive, Iceberg (включая системные таблицы), Paimon, JDBC Catalog, обратная запись во внешние таблицы, Java UDFОколо 2.7 ГБ
apache/doris:all-in-one-<version>-fullВсё перечисленное выше, а также Hudi, коннектор Trino, MaxComputeОколо 3.2 ГБ

Указанные размеры представляют собой сумму размеров несжатых слоёв, измеренную для версии 4.1.3; около 0.2 ГБ в каждом образе занимает Meta Service, который используется только кластером с разделением вычислений и хранения. Для сравнения: те же компоненты без удаления отладочной информации и лишних каталогов занимают около 5.6 ГБ.

Выбирайте -full, только если тесты действительно читают таблицы Hudi, используют коннектор Trino или MaxCompute. В остальных случаях используйте тег без суффикса. Ни один из трёх режимов не требует определённого тега; кластеры Compose можно переключить на -full или на самостоятельно собранный тег с помощью переменной окружения DORIS_IMAGE.

Разница между двумя тегами обусловлена тем, как BE загружает сканеры: при запуске BE перебирает каталоги в be/lib/java_extensions/ для загрузки JNI-сканеров. Отдельного списка и параметра конфигурации нет, поэтому тег поддерживает ровно те форматы, каталоги которых входят в образ. Обратите внимание: чтение данных Hive и Iceberg выполняется встроенным в BE модулем чтения parquet / orc, а не этими JNI-сканерами, поэтому поддерживается обоими тегами.

Поддержка нескольких архитектур​

apache/doris:all-in-one-4.1.3 представляет собой индекс образов OCI, содержащий по одному манифесту для linux/amd64 и linux/arm64. Команда docker pull автоматически выбирает вариант, соответствующий архитектуре хоста, как и для apache/doris:fe-4.1.3, поэтому CI не нужны разные теги для исполнителей с разной архитектурой.

docker buildx imagetools inspect apache/doris:all-in-one-4.1.3
Примечание

Как правило, BE Doris не может работать при эмуляции другой архитектуры. Например, запуск образа amd64 с параметром --platform linux/amd64 на Apple Silicon завершается ошибкой сегментации; официальные образы apache/doris:be-* ведут себя так же. Запускайте образ на реальном оборудовании соответствующей архитектуры.

Один контейнер: окружение для интеграционных тестов​

Проектам экосистемы Apache Doris, таким как коннекторы, SDK и инструменты интеграции данных, для запусков e2e / CI обычно нужен настоящий экземпляр Doris вместо имитации. Режим с одним контейнером предназначен именно для этого: один FE и один BE в одном контейнере, готовые к использованию после запуска, позволяют подключить его как тестовое окружение.

Возможности, важные для интеграционного тестирования:

ВозможностьОписание
Готовность к работеЗапуск FE, регистрация BE командой ALTER SYSTEM ADD BACKEND и ожидание перехода BE в рабочее состояние выполняются внутри контейнера. Внешний скрипт не требуется
Проверка состоянияОбраз содержит HEALTHCHECK, который переходит в состояние healthy, только когда FE готов и BE работает, обычно в течение 20 секунд. CI может ждать этого состояния вместо вызова sleep
Одна репликаЗадано force_olap_table_replication_num = 1, поэтому для CREATE TABLE не требуется replication_num
Ограниченные ресурсыПотребление памяти уменьшено с учётом ресурсов исполнителей CI: куча FE -Xmx2048m, куча JNI на стороне BE -Xmx1024m и параметр BE mem_limit = 40%
Немедленное завершение при сбоеЕсли FE или BE завершает работу, контейнер сразу завершается с ненулевым кодом, а не перезапускает процесс незаметно, поэтому сбой немедленно становится виден в CI
Корректная остановкаdocker stop сначала останавливает BE, затем FE и завершается с кодом 0
Несколько архитектурОдин тег охватывает linux/amd64 и linux/arm64

Информация для подключения​

ПараметрОписание
Протокол MySQLПорт 9030, пользователь root, без пароля
FE HTTPПорт 8030, /api/health не требует аутентификации
BE HTTPПорт 8040, конечная точка Stream Load
Проверка доступности BEПорт 9050, используется внутри контейнера, обычно не пробрасывается на хост

Обычный docker run​

docker run -d --name doris \
-p 9030:9030 -p 8030:8030 -p 8040:8040 \
apache/doris:all-in-one-4.1.3

# Wait until the container is healthy
until [ "$(docker inspect -f '{{.State.Health.Status}}' doris)" = healthy ]; do sleep 1; done

mysql -uroot -h127.0.0.1 -P9030 -e "SHOW BACKENDS"

Образ содержит клиент MySQL, поэтому, если на хосте его нет, запустите его внутри контейнера:

docker exec doris mysql -uroot -h127.0.0.1 -P9030 -e "SHOW BACKENDS"

Docker Compose​

При использовании depends_on и service_healthy тестовый контейнер запускается только после того, как Doris действительно готов к работе:

services:
doris:
image: apache/doris:all-in-one-4.1.3
ports: ["9030:9030", "8030:8030", "8040:8040"]

integration-test:
image: my-project-tests:latest
depends_on:
doris:
condition: service_healthy

GitHub Actions​

Если Doris используется как сервисный контейнер, GitHub Actions ждёт, пока контейнер перейдёт в состояние healthy, прежде чем выполнять steps, поэтому тестовому коду не нужна собственная логика повторных попыток и ожидания:

jobs:
e2e:
runs-on: ubuntu-latest
services:
doris:
image: apache/doris:all-in-one-4.1.3
ports: ['9030:9030', '8030:8030', '8040:8040']
steps:
- uses: actions/checkout@v4
- run: mvn -B verify -Pe2e

Настройка конфигурации​

Образ уже содержит набор настроек по умолчанию для интеграционных тестов. Чтобы изменить их, используйте перечисленные ниже переменные окружения; они записываются в fe.conf / be.conf при запуске контейнера, причём последнее присваивание имеет приоритет:

docker run -d --name doris \
-p 9030:9030 -p 8030:8030 -p 8040:8040 \
-e BE_CONFIG_EXTRA="mem_limit = 80%" \
-e FE_CONFIG_EXTRA="qe_max_connection = 2048" \
-e FE_HEAP=4096m \
apache/doris:all-in-one-4.1.3
Переменная окруженияДействие
FE_CONFIG_EXTRAДобавляется в конец fe.conf. Разделяйте несколько параметров переводами строк
BE_CONFIG_EXTRAДобавляется в конец be.conf. Разделяйте несколько параметров переводами строк
FE_HEAP / BE_HEAPПереопределяют -Xmx JVM на стороне FE / BE, например 4096m; значения по умолчанию составляют 2048m и 1024m

Сохранение данных: по умолчанию данные не сохраняются и удаляются вместе с контейнером, что обычно и требуется для CI. Чтобы сохранить данные, подключите каталоги /opt/apache-doris/fe/doris-meta и /opt/apache-doris/be/storage. Процедура запуска идемпотентна, поэтому один и тот же каталог данных можно использовать при повторных запусках.

Устранение неполадок​

  • docker logs <container> содержит журнал запуска entrypoint и вывод консоли FE, по которым можно определить, на каком этапе остановился запуск кластера.
  • Полные журналы находятся внутри контейнера в fe/log/fe.log и be/log/be.INFO.
  • Завершение контейнера с ненулевым кодом означает, что FE или BE аварийно завершил работу. Запись в журнале непосредственно перед завершением указывает, какой именно процесс завершился и какой файл журнала следует прочитать.
  • Для тестов с большими объёмами данных может потребоваться увеличить vm.max_map_count на хосте (sysctl -w vm.max_map_count=2000000). Этот параметр sysctl не изолирован пространствами имён, поэтому контейнер не может его установить; по этой причине образ пропускает его проверку в start_be.sh.

Многоузловые кластеры и кластеры с разделением вычислений и хранения​

Два файла Compose находятся в каталоге docker/runtime/all-in-one/4.1/compose/ основного репозитория Doris и требуют Docker Compose v2 (подкоманду docker compose). По умолчанию используется образ apache/doris:all-in-one-4.1.3; его можно изменить через DORIS_IMAGE, задав переменную окружения или указав её в файле .env рядом с файлом Compose. Все остальные параметры передаются таким же образом, а полный их список приведён в комментарии в начале каждого файла.

cd <doris repository>/docker/runtime/all-in-one/4.1/compose

Оба файла содержат сервис client: он переходит в состояние healthy, только когда все узлы работают; именно этого ждёт docker compose up --wait. Затем он остаётся в ожидании внутри сети кластера и предоставляет mysql и curl, поэтому к кластеру можно обращаться через docker compose exec client ....

Многоузловой кластер: multi-node.yml​

docker compose -f multi-node.yml up --wait          # healthy in about 35 s
docker compose -f multi-node.yml exec client mysql -uroot -hfe-1 -P9030
docker compose -f multi-node.yml kill fe-1 # a new master in a few seconds
docker compose -f multi-node.yml start fe-1 # rejoins as a follower
docker compose -f multi-node.yml down # tears the cluster down; nothing persists
fe-1 ─┬─ fe-2, fe-3
├─ be-1, be-2, be-3
└─ client
  • fe-1 создаёт кластер, а fe-2, fe-3 присоединяются в роли follower; FE3_ROLE=observer переводит fe-3 в роль observer.
  • По умолчанию таблицы имеют три реплики, по одной на каждый BE, как в настоящем кластере.
  • Порты хоста: 9030 / 8030 для fe-1, 9031 / 8031 для fe-2, 9032 / 8032 для fe-3 и 8040 для HTTP-порта be-1.
  • Параметры: DORIS_IMAGE, SUBNET (по умолчанию 172.31.81), порты хоста, FE_HEAP (по умолчанию 1024m), BE_MEM_LIMIT (по умолчанию 25%), FE3_ROLE.

Кластер с разделением вычислений и хранения: cloud.yml​

docker compose -f cloud.yml up --wait                  # 1 FE + 3 BE, healthy in about 50 s
docker compose -f cloud.yml --profile ha up --wait # ... plus two follower FEs, 3 FEs in total
docker compose -f cloud.yml exec client mysql -uroot -hfe-1 -P9030
docker compose -f cloud.yml down # tears the cluster down; nothing persists
fdb ─ fdb-init ─┬─ ms ─ cloud-init ─ fe-1 ─┬─ be-1, be-2  (cg_a)
└─ recycler ├─ be-3 (cg_b)
minio ─ minio-init ─┘ └─ client
  • Все процессы Doris (FE, BE, Meta Service, Recycler) запускаются из образа «всё в одном»; FoundationDB и MinIO используют образы своих исходных проектов.
  • cloud-init представляет собой контейнер для однократного выполнения, который создаёт экземпляр в Meta Service в режиме storage vault с MinIO в качестве хранилища (адресация path-style, обычный HTTP); затем fe-1 назначает built_in_storage_vault хранилищем по умолчанию, поэтому CREATE TABLE работает без явного указания хранилища. Оба шага идемпотентны.
  • Три узла BE образуют две вычислительные группы: be-1 и be-2 входят в cg_a, а be-3 входит в cg_b. Такое окружение позволяет выполнять use @cg_b, SHOW COMPUTE GROUPS, ALTER SYSTEM ADD BACKEND ... ("tag.compute_group_name" = ...), проверять storage vault, прогрев данных и переключение FE при отказе в облачном режиме, а также наблюдать, как объекты появляются в MinIO.
  • Порты хоста: 9030 / 8030 для fe-1 (9031 / 8031 и 9032 / 8032 для fe-2 и fe-3 при использовании профиля ha), 8040 для HTTP-порта be-1, 15000 для HTTP API Meta Service (5000 занят AirPlay в macOS), 9000 для MinIO и 9001 для консоли MinIO (minioadmin / minioadmin).
  • Параметры: DORIS_IMAGE, SUBNET (по умолчанию 172.31.80), порты хоста, FE_HEAP, BE_MEM_LIMIT, CG_A / CG_B (имена вычислительных групп), INSTANCE_ID (по умолчанию 100001, также используется как cluster_id узлов FE), S3_BUCKET / S3_AK / S3_SK, FDB_IMAGE / FDB_PLATFORM.
  • Кластер, запущенный с --profile ha, следует останавливать и удалять с тем же флагом, чтобы fe-2 и fe-3 из этого профиля обрабатывались вместе с остальными компонентами.

Что нужно знать​

  • Сохранение данных. Команды docker compose stop / start (или повторный up) сохраняют данные; создание экземпляра, назначение хранилища по умолчанию и регистрация узлов идемпотентны. Команда down удаляет контейнеры и сеть, а вместе с ними и данные.
  • Адреса узлов. Узлы получают фиксированные IP-адреса в частной подсети (SUBNET, по умолчанию 172.31.81 для многоузлового кластера и 172.31.80 для облачного), поэтому после перезапуска контейнер сохраняет идентификатор, под которым он известен Doris. В файлах используются разные подсети, поэтому оба кластера могут работать одновременно, если одному из них назначить другие порты хоста.
  • Доступ с хоста. Используйте опубликованные порты. В Docker Desktop (macOS / Windows) адреса контейнеров недоступны для маршрутизации с хоста, поэтому Stream Load, запущенный с хоста, не сможет последовать перенаправлению FE на BE; запускайте его из сервиса client (docker compose -f <file> exec client curl ...). На хостах Linux узлы доступны напрямую.
  • Память. Значения по умолчанию составляют FE_HEAP=1024m и mem_limit = 25% для каждого BE. Полный кластер с разделением вычислений и хранения занимает около 9 ГБ; выделите Docker Desktop не менее 12 ГБ и не рассчитывайте разместить обе топологии одновременно на виртуальной машине с 16 ГБ памяти.
  • FoundationDB на Apple Silicon. Исходные образы foundationdb/foundationdb:7.1.x доступны только для amd64, поэтому на Apple Silicon fdb работает под эмуляцией, что допустимо для этих задач; заменить образ и платформу можно через FDB_IMAGE / FDB_PLATFORM. Meta Service скомпонован с клиентской библиотекой 7.1, поэтому используйте сервер 7.1.
  • Проверка работоспособности. compose/smoke-test.sh <multi-node|cloud> [image:tag] запускает топологию с отдельным именем проекта, подсетью и портами хоста, проверяет реплики или вычислительные группы и хранилище, выполняет Stream Load через клиент, принудительно завершает ведущий FE, перезапускает BE, пока прежний ведущий узел недоступен, возвращает ведущий узел в работу и удаляет всё окружение. Около двух минут на каждую топологию.

Роли контейнеров: DORIS_ROLE​

Оба файла Compose используют роли одного и того же образа; entrypoint определяет по DORIS_ROLE, что должен запускать контейнер. Таким же образом можно собрать собственную топологию, например 1 FE + 5 BE:

DORIS_ROLEЧто запускаетсяОбязательные переменные
all (по умолчанию)FE + BE в одном контейнере, то есть режим с одним контейнеромнет
feОдин FE. Создаёт новый кластер, если FE_MASTER пуст; в противном случае регистрируется в роли FE_ROLE (follower | observer) и присоединяется к кластеруFE_MASTER
beОдин BE, регистрируемый через FE_MASTER; в режиме с разделением вычислений и хранения входит в вычислительную группу, имя которой задано в COMPUTE_GROUPFE_MASTER
ms / recyclerMeta Service / Recycler для режима с разделением вычислений и храненияFDB_CLUSTER
cloud-initОднократное выполнение: создаёт экземпляр с разделением вычислений и хранения на основе S3-совместимого объектного хранилища, затем завершает работуMS_ENDPOINT, INSTANCE_ID, S3_*
clientОжидает появления работающих узлов в количестве EXPECT_FE / EXPECT_BE, затем остаётся в ожидании с доступными mysql и curlFE_MASTER
  • DEPLOY_MODE=cloud переводит fe и be в режим разделения вычислений и хранения (параметры deploy_mode, meta_service_endpoint, файловый кеш и прочие настройки записываются автоматически); FE использует INSTANCE_ID в качестве своего cluster_id и управляет узлами через SQL, поэтому назначать cloud_unique_id не требуется.
  • FE_MASTER может содержать список нескольких FE (fe-1,fe-2,fe-3): используется первый ответивший узел, поэтому перезапуск узла не задерживается из-за ожидания FE, который в данный момент недоступен. FE, у которого уже есть метаданные, присоединяется повторно самостоятельно.
  • Все роли учитывают FE_CONFIG_EXTRA / BE_CONFIG_EXTRA / MS_CONFIG_EXTRA и FE_HEAP / BE_HEAP, а после запуска создают флаг готовности, на который ориентируется HEALTHCHECK образа. Поэтому docker compose up --wait ждёт формирования всего кластера, а аварийное завершение процесса по-прежнему приводит к завершению контейнера с ненулевым кодом.
  • Настройки, зависящие от топологии (priority_networks, число реплик, балансировка, параметры разделения вычислений и хранения), записываются entrypoint для каждой роли при запуске контейнера; встроенные в образ файлы конфигурации содержат только значения по умолчанию, связанные с объёмом ресурсов.

Самостоятельная сборка образа​

Dockerfile и скрипт сборки находятся в каталоге docker/runtime/all-in-one/<release-line>/ основного репозитория Doris; сейчас доступна линейка 4.1. Структура артефактов в разных линейках релизов различается достаточно сильно, поэтому каждой выделен собственный каталог вместо переключения версий внутри единого Dockerfile.

build.sh является единственной точкой входа, а сам скрипт можно запускать из любого каталога:

# Build both the base and the -full tag from the official 4.1.3 component images
# (fe / be / ms), host architecture only
./build.sh -v 4.1.3

# Build base only, then run a smoke test against it
./build.sh -v 4.1.3 -f base -t

# Build from a local ./output, which is handy for verifying your own changes.
# Build Doris with build.sh --fe --be --cloud first; without --cloud there is no
# ./output/ms and the resulting image cannot serve the compute-storage separated cluster
./build.sh -v dev -s local

# Build from an extracted release tarball, e.g. while the component images of a
# new release are not on Docker Hub yet
./build.sh -v 4.1.4 -s tarball --tarball-dir ~/apache-doris-4.1.4-bin-x64

Контекстом сборки всегда служит корень репозитория (его содержимое сокращается до нескольких КБ с помощью Dockerfile.dockerignore); локальный ./output или каталог распакованного архива передаётся как именованный контекст BuildKit, поэтому может находиться где угодно, но для этого требуется docker buildx. Самостоятельно собранный образ можно напрямую использовать с обоими файлами Compose:

DORIS_IMAGE=apache/doris:all-in-one-dev docker compose -f multi-node.yml up --wait

Без --platform сборка выполняется только для архитектуры хоста. Для сборки под несколько архитектур их нужно указать явно, например ./build.sh -v 4.1.3 --platform linux/amd64,linux/arm64 --push. Поскольку сборка для другой архитектуры использует эмуляцию и занимает много времени, для релиза лучше собирать каждую архитектуру на отдельной машине соответствующей архитектуры, а затем объединять результаты с помощью docker buildx imagetools create.

./build.sh --help выводит остальные параметры.

подсказка

Подробности реализации, в том числе что удаляется из образа, почему нельзя удалять некоторые каталоги, похожие на необязательные компоненты для внешних таблиц, на что расходуется место и как запускать проверку работоспособности, см. в README в этом каталоге.