Централизованная конфигурация: etcd / config storage

Рейтинг: 79.6% · 15 голосов
Исчерпывающий курс по Tarantool 3.x: модель данных, движки memtx и vinyl, Lua и файберы, транзакции и MVCC, SQL, конфигурация (box.cfg и декларативная 3.x), репликация и Raft, шардирование vshard, эксплуатация, безопасность. 47 уроков со схемами.
Ответить
Аватара пользователя
denis_tnt
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Централизованная конфигурация: etcd / config storage

Сообщение denis_tnt »

Оглавление курса (47)
  1. Что такое Tarantool: in-memory СУБД и сервер приложений
  2. Архитектура изнутри: процесс, потоки, event-loop
  3. Установка и первый запуск: tt CLI, пакеты, Docker
  4. Интерактив: консоль, admin-консоль, первые команды
  5. Спейсы и кортежи: форматы, типы данных
  6. Типы индексов и их применимость
  7. Движки хранения: memtx vs vinyl
  8. DDL: схема, создание спейсов и индексов, миграции
  9. DML и выборки: insert/update/upsert, итераторы
  10. Персистентность: WAL, снапшоты, recovery
  11. Внутренности memtx: аллокаторы slab/arena, память
  12. Внутренности vinyl: LSM, компакция, тюнинг
  13. Lua и LuaJIT в Tarantool: box, модули, rocks
  14. Файберы: кооперативная многозадачность, каналы
  15. Транзакции: ACID, изоляция, MVCC
  16. Хранимые процедуры, модули, организация приложения
  17. net.box: удалённые вызовы, async
  18. Пулы соединений, балансировка, реконнект
  19. Ошибки и диагностика: box.error, pcall
  20. Типы и сериализация: MsgPack, decimal, datetime, uuid
  21. SQL в Tarantool: возможности и связь с box
  22. SQL: таблицы, JOIN, подзапросы, представления
  23. SQL: подготовленные выражения, транзакции, Lua-интероп
  24. Классическая конфигурация box.cfg (legacy 1.x/2.x)
  25. Декларативная конфигурация 3.x: config.yaml, иерархия
  26. Роли и приложения в 3.x
  27. Централизованная конфигурация: etcd / config storage (вы здесь)
  28. tt CLI глубоко: разработка, сборка, запуск
  29. Cartridge (официальный legacy) и миграция на 3.x
  30. Репликация: replicaset, топологии
  31. Механика репликации: WAL-стриминг, vclock
  32. Синхронная репликация и выборы лидера (Raft)
  33. Жизненный цикл узла: bootstrap, join, rejoin
  34. vshard: router/storage, виртуальные бакеты
  35. Решардинг и rebalancing бакетов
  36. Запросы поверх шардов: map-reduce, crud
  37. Мониторинг: метрики, Prometheus, Grafana
  38. Логирование и аудит
  39. Бэкапы и восстановление
  40. Безопасность: аутентификация, RBAC, TLS
  41. Производительность: профилирование, тюнинг
  42. Обновления: схема, rolling upgrade
  43. Деплой в продакшен: Docker, топология (официальные паттерны)
  44. Администрирование через официальный TCM (Tarantool Cluster Manager)
  45. Коннекторы: Python, Go, Java
  46. Ключевые модули (rocks): crud, metrics, queue, expirationd
  47. Capstone: шардированный отказоустойчивый кластер
Зачем нужно централизованное хранилище

В прошлых уроках конфиг лежал в локальном YAML рядом с каждым экземпляром. Это работает, но в кластере из десятков инстансов появляется боль: один и тот же config.yaml нужно положить на все машины, и при любой правке - заново разложить везы и проследить, чтобы файлы не разъехались. Один забытый узел со старым файлом - и у вас рассинхрон топологии.

Централизованное хранилище решает это так: единственный источник правды - внешнее распределённое key-value хранилище, а каждый инстанс при старте сам идёт туда и забирает свой кусок конфигурации. Tarantool 3.x поддерживает два типа такого хранилища:
  • etcd - внешний распределённый KV-стор на алгоритме Raft (де-факто стандарт в мире Kubernetes).
  • Tarantool-based config storage - реплика-сет самого Tarantool со встроенной ролью config.storage, который хранит конфиг в синхронных (raft-подобных) спейсах.
Важно: централизованные хранилища конфигурации - фича только Enterprise Edition. В Community Edition доступен лишь локальный YAML. Дальше речь про EE.
Как это устроено внутри: кворум и распространение

Главная идея - конфиг хранится не на одной ноде, а в кластере из нечётного числа узлов (обычно 3 или 5), которые держат данные согласованно через кворум.

Кворум etcd (Raft). etcd-кластер выбирает лидера; запись считается зафиксированной (committed), только когда её подтвердило большинство узлов - (N/2)+1. Для трёх узлов кворум - 2, значит кластер переживёт падение одного узла. Для пяти - переживёт падение двух. Когда вы делаете put конфига, лидер реплицирует запись в свой Raft-лог, ждёт подтверждения большинства и только потом отвечает "ок". Поэтому опубликованный конфиг сразу консистентен: любой инстанс, читающий с любого живого узла, увидит одну и ту же версию.

Раскладка ключей. Tarantool ищет конфигурацию по фиксированному шаблону:

Код: Выделить всё

<prefix>/config/*
. Префикс задаёте вы (он должен начинаться со слэша, например /myapp). Команда tt cluster publish кладёт весь кластерный конфиг по пути

Код: Выделить всё

/myapp/config/all
. Можно дробить на несколько ключей (например /myapp/config/all и отдельные оверрайды) - Tarantool сольёт все ключи под префиксом в одну итоговую конфигурацию.

Доставка и watch. Инстанс при старте подключается к endpoint-ам, читает все ключи под префиксом, склеивает их и применяет к себе только релевантную часть (своя группа -> реплика-сет -> instance). После старта он не опрашивает хранилище в цикле, а вешает watch на префикс. etcd сам шлёт уведомление при изменении ключа - инстанс получает его и применяет новый конфиг на лету, без рестарта. Это и есть автоматический reload.

Изображение
Публикация и watch-доставка конфига через кворум etcd

Ключевые команды и конфиги

1. Публикация конфига в etcd. Через tt (умеет и etcd, и Tarantool-стор):

Код: Выделить всё

# source.yaml - это полный кластерный конфиг
tt cluster publish "http://user:pass@localhost:2379/myapp" source.yaml

# посмотреть, что лежит в хранилище
tt cluster show "http://user:pass@localhost:2379/myapp"
То же напрямую через etcdctl (для etcd < 3.4 нужно ETCDCTL_API=3):

Код: Выделить всё

etcdctl put /myapp/config/all < source.yaml
2. Локальный конфиг инстанса - только как подключиться к хранилищу. Сам инстанс конфигурации почти не содержит, лишь секцию config.etcd:

Код: Выделить всё

config:
  etcd:
    endpoints:
      - http://localhost:2379
    prefix: /myapp
    username: sampleuser
    password: '123456'
    http:
      request:
        timeout: 3
Грабли: внутри конфига, который лежит в etcd, секции config.etcd быть НЕ должно. Connection-настройки - это про то, как достать конфиг; класть их внутрь самого конфига нельзя (получите ошибку валидации).
3. Старт без локального файла - через переменные окружения:

Код: Выделить всё

export TT_CONFIG_ETCD_ENDPOINTS=http://localhost:2379
export TT_CONFIG_ETCD_PREFIX=/myapp
tarantool --name instance001
4. Reload. По умолчанию reload автоматический (через watch). Можно переключить на ручной:

Код: Выделить всё

config:
  reload: 'manual'
  etcd:
    # ...
Тогда новый конфиг подхватывается только явной командой в консоли или коде:

Код: Выделить всё

require('config'):reload()
-- проверить текущий статус применения
require('config'):info()
Tarantool-based storage вместо etcd: роль config.storage на реплика-сете, при этом обязательно

Код: Выделить всё

replication.failover: election
(Raft-выборы лидера, дают свой кворум) и

Код: Выделить всё

database.use_mvcc_engine: true
- MVCC нужен, чтобы чтения конфига были линеаризуемыми, то есть читатель не получил устаревшую версию с отставшей реплики.

Частые заблуждения и грабли
  • "Можно держать 2 узла etcd для отказоустойчивости". Нет. Кворум из 2 - это 2, падение любого узла останавливает запись. Нужно нечётное число: 3 или 5. Два узла хуже одного по доступности записи.
  • "etcd упал - кластер встанет". Уже стартовавшие инстансы продолжат работать на последнем применённом конфиге; недоступным станет только reload и старт новых инстансов. Но если в этот момент инстанс перезапустится, он не сможет подняться без хранилища.
  • "reload применит всё что угодно". Reload применяет только изменяемые в рантайме опции. Параметры вроде имени инстанса, путей к WAL/снапшотам, listen-порта при reload не меняются - для них нужен рестарт.
  • "Префикс можно писать без слэша". Префикс обязан начинаться со слэша; Tarantool ищет строго по

    Код: Выделить всё

    <prefix>/config/*
    .
  • Failover-координатор. Если используете

    Код: Выделить всё

    replication.failover: supervised
    , etcd дополнительно хранит состояние координаторов отказоустойчивости. Это ещё один аргумент за надёжный кворум хранилища.
Мини-лаба
  • Поднимите одноузловой etcd (для лабы кворум из одного достаточен): . Положите минимальный кластерный конфиг:

    Код: Выделить всё

    etcdctl put /myapp/config/all < source.yaml
    . Запустите инстанс с TT_CONFIG_ETCD_ENDPOINTS и TT_CONFIG_ETCD_PREFIX. Затем измените один параметр (например log.level), сделайте повторный put и проверьте в консоли инстанса через

    Код: Выделить всё

    require('config'):info()
    , что конфиг подхватился сам, без рестарта.
Контрольные вопросы
  • Сколько узлов etcd переживёт кластер из 5 без потери записи и почему именно столько?
  • По какому шаблону пути Tarantool ищет конфигурацию в etcd и что произойдёт, если префикс задать без ведущего слэша?
  • Чем отличается поведение при reload: 'manual' от поведения по умолчанию, и за счёт какого механизма работает автоматический режим?
  • Зачем для Tarantool-based config storage обязательно включать MVCC и failover: election?
👍3 ❤️4 🔥2 😄 🤔3
Ответить
← Предыдущая глава
Роли и приложения в 3.x
Следующая глава →
tt CLI глубоко: разработка, сборка, запуск

Все главы курса «Tarantool: in-memory СУБД и сервер приложений с нуля до продакшена»

Поделиться темой: ✈ Telegram VK

Вернуться в «Tarantool: СУБД и сервер приложений»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость