Локальная конфигурация кластера и экземпляра
Конфигурация кластера в Tarantool задает общие параметры кластера, одинаковые для всех узлов кластера, и клиентский код миграций.
Копия такой конфигурации хранится на каждом экземпляре, входящем в состав кластера, а сам кластер автоматически синхронизирует
эти копии.
Конфигурация кластера определяет топологию кластера, восстановление после сбоев (failover),
параметры vshard, настройки аутентификации, управление списками контроля доступа (ACL), а также настройки, устанавливаемые пользователем.
Конфигурация кластера не содержит параметры для конкретного экземпляра — порты, рабочие каталоги и настройки
памяти.
Содержание:
- Представление кластерной конфигурации
- Настройка параметров роли
- Загрузка конфигурации кластера
- Пример работы с кластерной конфигурацией
Представить кластерную конфигурацию можно двумя способами:
-
Единый YAML-файл — заданные секции конфигурации собраны в одном файле
config.yml. Секции конфигурации представлены в виде соответствующего блока внутри файла. Это представление конфигурации компактно, его удобно использовать для хранения и передачи данных. -
Несколько YAML-файлов — каждая секция конфигурации находится в отдельном файле. Этот подход позволяет гибко управлять конфигурацией и редактировать отдельные ее части.
Пример единого файла конфигурации config.yml:
# config.yml---auth: { ... }crud: { ... }metrics: { ... }migrations: { ... }topology: { ... }schema: { ... }user_custom_config: { ... }vshard_groups: { ... }...
В файловой системе схема конфигурации кластера имеет вид древовидной структуры.
Директория config содержит основные секции конфигурации.
По умолчанию в директории определены три секции конфигурации: auth.yml, topology.yml и vshard_groups.yml.
config/├── auth.yml├── topology.yml└── vshard_groups.yml
По мере добавления пользовательских секций конфигурации схема увеличивается:
config/├── auth.yml├── crud.yml├── metrics.yml├── migrations.yml├── schema.yml├── user_custom_config.yml└── vshard_groups.yml
В конфигурации кластера можно хранить данные и параметры для конкретной роли.
Конфигурация кластера поддерживает формат YAML, а также обычные текстовые разделы.
Чтобы упорядочить разделы, можно использовать вложенные каталоги:
# config.yml---migrations/source/001_init.lua: { ... }...
Пример структуры с вложенным каталогом:

Гибкость конфигурации кластера позволяет изменять систему под различные потребности, в том числе под требования конкретных ролей.
Есть несколько способов обновить конфигурацию кластера:
- Lua API — обеспечивает программную гибкость и позволяет автоматизировать процесс;
- HTTP API — позволяет удобно работать с кластером с помощью стандартных HTTP-запросов;
- веб-интерфейс Tarantool DB;
- GraphQL API.
Чтобы обновить конфигурацию через веб-интерфейс, выполните следующие шаги:
- В веб-интерфейсе перейдите на вкладку Configuration files.
- При необходимости скачайте текущую версию конфигурационного файла, нажав на кнопку Download.
- Внесите необходимые изменения в конфигурационный файл.
Добавлять, изменять и удалять можно любые разделы, кроме системных (например,
topology,vshard,vshard_groups). - Нажмите кнопку Upload configuration, чтобы применить обновленный файл конфигурации. Кластер проверяет изменения, отклоняя неприемлемые, а затем распространяет новую конфигурацию по всем узлам кластера. Если файл обновлен успешно, появится соответствующее сообщение в нижней части экрана. Если при попытке применить новые настройки возникла проблема, появится сообщение об ошибке.
Чтобы объединить несколько конфигураций в единый файл, можно использовать HTTP API. HTTP API работает только с одним файлом конфигурации старого образца.
В примере ниже создан файл конфигурации config.yml:
cat > config.yml << CONFIG---custom_section: { }...CONFIG
Загрузить новую конфигурацию в кластер можно следующей командой:
curl -v "localhost:8081/admin/config" -X PUT --data-binary @config.yml
Скачать текущую конфигурацию из кластера можно так:
curl -v "localhost:8081/admin/config" -o config.yml
Скачать можно только разделы, связанные с ролями.
Скачать или загрузить системные разделы (например, topology, auth, users_acl) не получится.
Если включена авторизация, используйте параметр --user с учетными данными
пользователя: --user username:password.
Этот параметр обеспечивает безопасное взаимодействие с API, требующим аутентификации.
GraphQL API передаёт содержимое каждой секции конфигурации как обычную текстовую строку. Cartridge сохраняет исходную строку без повторной сериализации YAML, поэтому порядок ключей, комментарии и форматирование внутри секции сохраняются. Этот API используется на вкладке Code веб-интерфейса Cartridge при чтении, проверке и применении конфигурации.
В примерах ниже в кластерной конфигурации уже есть два прикладных файла: app_config.yml и test.yml.
Исходное состояние на вкладке Code:

При обновлении через GraphQL передаётся содержимое отдельного файла конфигурации.
Имя файла указывается отдельно, в поле filename.
Передавать дополнительный верхнеуровневый ключ app_config: при этом не нужно.
Исходное содержимое app_config.yml, которое передаётся в поле content:
---zeta: 1alpha: 2gamma: 3options:charlie.enabled: 'true'bravo.timeout: '30'alpha.retries: '5'delta: 4groups:first:- name: group-onelabel: LABEL_ONEtags:- TAG_Asecond:- name: group-twolabel: LABEL_TWO...
Содержимое test.yml — одна строка без завершающего переноса строки:
['a', 'b', {c: "d"}] ###
Порядок ключей в app_config.yml задан намеренно: по нему можно проверить, что после применения конфигурации
поля остались на своих местах. Файл test.yml также позволяет проверить сохранение кавычек, комментария и записи YAML в одну строку.
По умолчанию GraphQL API доступен по адресу http://<host>:<port>/admin/api, например
http://127.0.0.1:8081/admin/api.
Если в Cartridge настроен параметр webui_prefix, он также должен присутствовать в URL:
http://<host>:<port>/<webui_prefix>/admin/api.
Если включена авторизация, также требуется указать учётные данные в команде curl.
Если авторизация отключена, этот параметр указывать не нужно.
--user 'username:password'
Для удобства адрес и учётные данные можно задать через переменные окружения:
export CARTRIDGE_URL='http://127.0.0.1:8081'export CARTRIDGE_USER='username'export CARTRIDGE_PASSWORD='password'
Получить секцию app_config.yml можно так:
curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary '{"query": "query($sections: [String!]) { cluster { config(sections: $sections) { filename content } } }","variables": {"sections": ["app_config.yml"]}}' \"$CARTRIDGE_URL/admin/api" |jq .
Пример ответа:
{"data": {"cluster": {"config": [{"filename": "app_config.yml","content": "---\nzeta: 1\nalpha: 2\ngamma: 3\noptions:\n charlie.enabled: 'true'\n bravo.timeout: '30'\n alpha.retries: '5'\ndelta: 4\ngroups:\n first:\n - name: group-one\n label: LABEL_ONE\n tags:\n - TAG_A\n second:\n - name: group-two\n label: LABEL_TWO\n...\n"}]}}}
В JSON переносы строк внутри content представлены как \n.
Если требуется вывести только исходный YAML без JSON-обёртки, замените jq . на
jq -r '.data.cluster.config[0].content'.
В этом случае вывод будет таким:
---zeta: 1alpha: 2gamma: 3options:charlie.enabled: 'true'bravo.timeout: '30'alpha.retries: '5'delta: 4groups:first:- name: group-onelabel: LABEL_ONEtags:- TAG_Asecond:- name: group-twolabel: LABEL_TWO...
Получить список всех файлов и их содержимого можно так:
curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary '{"query": "query { cluster { config { filename content } } }"}' \"$CARTRIDGE_URL/admin/api" |jq .
Пример ответа для двух исходных файлов:
{"data": {"cluster": {"config": [{"filename": "test.yml","content": "['a', 'b', {c: \"d\"}] ###"},{"filename": "app_config.yml","content": "---\nzeta: 1\nalpha: 2\ngamma: 3\noptions:\n charlie.enabled: 'true'\n bravo.timeout: '30'\n alpha.retries: '5'\ndelta: 4\ngroups:\n first:\n - name: group-one\n label: LABEL_ONE\n tags:\n - TAG_A\n second:\n - name: group-two\n label: LABEL_TWO\n...\n"}]}}}
Порядок файлов в массиве config может отличаться; порядок ключей внутри строки content сохраняется.
Чтобы получить только список имён файлов, замените jq . на jq -r '.data.cluster.config[].filename'.
Пример вывода списка имён:
test.ymlapp_config.yml
Перед применением конфигурации секцию рекомендуется проверить через validate_config.
Для правильного экранирования переносов строк и специальных символов используйте jq --rawfile.
Сохраните приведённое выше содержимое app_config.yml в локальный файл ./config/app_config.yml.
В примере отправляется тот же YAML, чтобы проверить сохранение порядка ключей и форматирования:
jq -n \--rawfile content './config/app_config.yml' \'{query: "query($sections: [ConfigSectionInput!]) { cluster { validate_config(sections: $sections) { error } } }",variables: {sections: [{filename: "app_config.yml",content: $content}]}}' |curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary @- \"$CARTRIDGE_URL/admin/api" |jq .
filename— имя секции (файла) в кластерной конфигурации;content— исходное текстовое содержимое файла;jq --rawfileчитает файл как строку и корректно экранирует его для JSON.
При успехе ответ выглядит так:
{"data": {"cluster": {"validate_config": {"error": null}}}}
Если проверка вернула описание ошибки в поле data.cluster.validate_config.error, конфигурация некорректна.
Также проверяйте верхнеуровневое поле errors, как описано в разделе Проверка ошибок.
Применить файл конфигурации app_config.yml можно так:
jq -n \--rawfile content './config/app_config.yml' \'{query: "mutation($sections: [ConfigSectionInput!]) { cluster { config(sections: $sections) { filename content } } }",variables: {sections: [{filename: "app_config.yml",content: $content}]}}' |curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary @- \"$CARTRIDGE_URL/admin/api" |tee /tmp/cartridge-config-response.json |jq .
Пример успешного ответа:
{"data": {"cluster": {"config": [{"filename": "app_config.yml","content": "---\nzeta: 1\nalpha: 2\ngamma: 3\noptions:\n charlie.enabled: 'true'\n bravo.timeout: '30'\n alpha.retries: '5'\ndelta: 4\ngroups:\n first:\n - name: group-one\n label: LABEL_ONE\n tags:\n - TAG_A\n second:\n - name: group-two\n label: LABEL_TWO\n...\n"}]}}}
Здесь:
filename— имя секции (файла) в кластерной конфигурации;content— исходное текстовое содержимое файла;jq --rawfileчитает файл как строку и корректно экранирует его для JSON;--data-binary @-передаёт сформированный JSON вcurlчерез стандартный ввод.
После применения повторите запрос одной секции с фильтром jq -r '.data.cluster.config[0].content'. Результат:
---zeta: 1alpha: 2gamma: 3options:charlie.enabled: 'true'bravo.timeout: '30'alpha.retries: '5'delta: 4groups:first:- name: group-onelabel: LABEL_ONEtags:- TAG_Asecond:- name: group-twolabel: LABEL_TWO...
Порядок полей, отступы и кавычки совпадают с исходным файлом: например, zeta остаётся перед alpha,
а в options ключи идут в порядке charlie.enabled, bravo.timeout, alpha.retries.
Чтобы передать несколько файлов в одном GraphQL-запросе, сохраните также исходное содержимое test.yml
в локальный файл ./config/test.yml без завершающего переноса строки. Затем выполните:
jq -n \--rawfile app_config './config/app_config.yml' \--rawfile test_config './config/test.yml' \'{query: "mutation($sections: [ConfigSectionInput!]) { cluster { config(sections: $sections) { filename content } } }",variables: {sections: [{filename: "app_config.yml",content: $app_config},{filename: "test.yml",content: $test_config}]}}' |curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary @- \"$CARTRIDGE_URL/admin/api" |jq .
Все перечисленные секции применяются в рамках одного обновления кластерной конфигурации.
Пример ответа:
{"data": {"cluster": {"config": [{"filename": "test.yml","content": "['a', 'b', {c: \"d\"}] ###"},{"filename": "app_config.yml","content": "---\nzeta: 1\nalpha: 2\ngamma: 3\noptions:\n charlie.enabled: 'true'\n bravo.timeout: '30'\n alpha.retries: '5'\ndelta: 4\ngroups:\n first:\n - name: group-one\n label: LABEL_ONE\n tags:\n - TAG_A\n second:\n - name: group-two\n label: LABEL_TWO\n...\n"}]}}}
Чтобы удалить файл из кластерной конфигурации, передайте для него content: null.
В примере удаляется app_config.yml:
curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary '{"query": "mutation($sections: [ConfigSectionInput!]) { cluster { config(sections: $sections) { filename content } } }","variables": {"sections": [{"filename": "app_config.yml","content": null}]}}' \"$CARTRIDGE_URL/admin/api" |jq .
Пример успешного ответа:
{"data": {"cluster": {"config": []}}}
Массив config в ответе пуст, поскольку запрошенная секция app_config.yml удалена.
Проверить её отсутствие можно повторным запросом:
curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary '{"query": "query($sections: [String!]) { cluster { config(sections: $sections) { filename content } } }","variables": {"sections": ["app_config.yml"]}}' \"$CARTRIDGE_URL/admin/api" |jq -r '.data.cluster.config[0].content'
Результат фильтра jq для отсутствующей секции:
null
На вкладке Code остаётся только test.yml:

Проверяйте не только HTTP-код ответа, но и верхнеуровневое поле errors.
GraphQL может вернуть HTTP 200, но при этом сообщить об ошибке выполнения.
Например, ответ на запрос применения ./config/app_config.yml можно сохранить и проверить так:
jq -n \--rawfile content './config/app_config.yml' \'{query: "mutation($sections: [ConfigSectionInput!]) { cluster { config(sections: $sections) { filename content } } }",variables: {sections: [{filename: "app_config.yml",content: $content}]}}' |curl --silent --show-error \--user "$CARTRIDGE_USER:$CARTRIDGE_PASSWORD" \--header 'Content-Type: application/json' \--data-binary @- \"$CARTRIDGE_URL/admin/api" \> /tmp/cartridge-config-response.jsonjq . /tmp/cartridge-config-response.jsonif jq -e '.errors and (.errors | length > 0)' \/tmp/cartridge-config-response.json >/dev/null; thenecho 'Cartridge вернул ошибку GraphQL' >&2exit 1fi
Например, при нарушении отступов в YAML вывод может выглядеть так.
Стек вызовов в поле extensions опущен:
{"errors": [{"message": "Error parsing section \"app_config.yml\": did not find expected key at document: 1, line: 7, column: 3\nwhile parsing a block mapping at line: 2, column: 1\n","extensions": {"io.tarantool.errors.class_name": "LoadConfigError"}}]}Cartridge вернул ошибку GraphQL
В этом случае скрипт выводит сообщение об ошибке и завершается с кодом 1.
Этот GraphQL-метод подходит для прикладных файлов, отображаемых на вкладке Code, — например, app_config.yml или log_level.yml,
однако через него нельзя управлять внутренними системными секциями Cartridge (topology, auth, vshard_groups, users_acl).
После изменения конфигурации шардированного кластера, например, при добавлении нового набора реплик или изменении веса шардов, начинается балансировка сегментов. При балансировке выполняется миграция сегментов — перенос сегментов с более нагруженных шардов на менее нагруженные.
Начиная с версии Tarantool DataBase 1.2.6 при старте балансировки кластер автоматически включает безопасный режим, чтобы обеспечить согласованность и целостность данных. Производительность кластера в этом режиме снижается (примерно на 15% для операций REPLACE). Безопасный режим включается независимо на каждом хранилище, участвующем в балансировке сегментов. Запросы к спейсам на движке vinyl всегда выполняются в безопасном режиме независимо от текущего статуса безопасного режима.
Проверить, включен ли безопасный режим, можно двумя способами:
- вызвать метод
crud.rebalance_safe_mode_status(); - проверить значение метрики
tnt_crud_storage_safe_mode_enabled.
Чтобы вернуть кластер в нормальный режим работы после окончания процесса балансировки, выполните следующие шаги:
-
Дождитесь полного завершения миграции сегментов.
-
Очистите кэш карты маршрутов на каждом роутере:
crud.rebalance.router_cache_clear()Проверить время последней очистки кэша можно с помощью метрики
tnt_crud_router_cache_clear_ts. -
Отключите безопасный режим вручную на каждом хранилище — как на мастер-узлах, так и на репликах:
crud.rebalance_safe_mode_disable()
Кроме того, существуют следующие особенности, касающиеся балансировки сегментов:
-
Поскольку во время миграции сегмента невозможно выполнять операции с кортежами в этом сегменте, CRUD-операции при балансировке могут завершаться с ошибками. Для исправления ошибок требуется повторно выполнить соответствующие запросы;
-
Когда
*_many-запрос выполняется над данными из нескольких шардов, на роутере эти данные автоматически разбиваются на пачки по шардам и параллельно отправляются на соответствующие узлы хранилища. Во время балансировки запрос может завершиться с ошибкой на некоторых хранилищах. В этом случае операция будет выполнена частично, а пользователю вернется ошибка с указанием хранилища, где не удалось выполнить запрос. Пользователю нужно быть готовым к тому, что операция может быть выполнена не полностью, и при необходимости повторить соответствующие запросы или выполнить другие необходимые действия; -
При выполнении операций SELECT во время балансировки часть записей в ответе может дублироваться или наоборот отсутствовать. Вероятность такого сценария увеличивается, если запросы на выборку выполняются по большому количеству шардов.
В примере добавлена роль crud, которая позволяет выполнять на кластере CRUD-операции
(создание, чтение, обновление, удаление) через IPROTO API.
Настроить эту роль можно тремя способами:
- через Lua API;
- через CLI — с помощью прямого подключения к экземплярам роутеров и настройки нужных параметров
crud; - с помощью кластерной конфигурации.
В примере ниже роль crud настроена с помощью кластерной конфигурации.
Есть два способа добавить конфигурацию в запущенный кластер:
- через веб-интерфейс Tarantool DB;
- через файл
config.yml.
Веб-интерфейс
-
В веб-интерфейсе Tarantool DB перейдите на вкладку Code.
-
Создайте файл
crud.yml. В нем будут храниться настройки ролиcrud. -
Укажите в файле конфигурацию ниже:
---stats: true...Здесь:
stats— включение сбора метрик CRUD.
-
Нажмите кнопку Apply.

Через веб-интерфейс можно менять состояние работы статистики и другие параметры в реальном времени без перезапуска кластера или экземпляров. Для этого поменяйте значение параметра и нажмите кнопку Apply.
Файл config.yaml
-
Перейдите в директорию
bootstrap. В ней хранится файлconfig.yaml. -
В
config.yamlдобавьте секциюcrudсо следующими настройками:crud:stats: true -
Структура файла теперь выглядит так:
