Деплой в продакшен: Docker, топология (официальные паттерны)

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

Деплой в продакшен: Docker, топология (официальные паттерны)

Сообщение 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: шардированный отказоустойчивый кластер
Краткий обзор

В этом уроке разбираем, как Tarantool 3.x официально едет в продакшен: из чего складывается рабочая топология кластера, где лежит конфигурация, кто назначает лидеров и как всё это упаковывается в Docker. Мы сознательно держимся ЧИСТОГО стека - только официальные компоненты: бинарь tarantool, утилита tt, образ tarantool/tarantool, централизованное хранилище конфигурации (etcd или сам Tarantool как config storage) и, для Enterprise, Tarantool Cluster Manager (TCM). Никакого кастомного HAProxy и самописных оркестраторов.

Главная мысль урока: в 3.x кластер - это не набор отдельных Lua-скриптов, а единая декларативная YAML-конфигурация, которая описывает всю топологию сразу. Запущенные процессы tarantool лишь читают свой кусок этой конфигурации и принимают роль (лидер, реплика, роутер, стораж).

Механика и архитектура

Кирпичики топологии. Минимальная единица отказоустойчивости - реплика-сет (replicaset): один лидер на запись плюс одна-две реплики на чтение. Реплика-сеты объединяются в группы (groups), а группы образуют кластер. Внутри реплика-сета работает full-mesh репликация: каждый инстанс соединён с каждым, поэтому в сети должны быть открыты iproto-порты (по умолчанию 3301 и далее) между всеми узлами.
Официальное требование к продакшену: минимум ТРИ физических или виртуальных машины. На двух нельзя построить честный кворум для синхронной репликации и выборов - кластер из двух узлов при сетевом разрыве не сможет безопасно выбрать лидера.
Декларативная конфигурация и иерархия. Конфигурация в 3.x строится по уровням: global -> group -> replicaset -> instance. Опция, заданная на верхнем уровне, наследуется вниз и может быть переопределена. Это позволяет, например, задать sharding.bucket_count один раз глобально, а advertise URI - на каждом инстансе. Топология описывается секциями groups -> replicasets -> instances.

Где живёт конфигурация. Два официальных способа:
  • Локальный config.yaml рядом с каждым инстансом - просто, но конфиг надо раскатывать на все узлы синхронно.
  • Централизованное хранилище: etcd или кластер Tarantool в роли config storage. Инстанс при старте получает в своём локальном config.yaml только адреса etcd (endpoints), префикс ключа (prefix) и креды, а саму топологию тянет из etcd. Изменили YAML в одном месте - все инстансы перечитали (режим auto или вручную). Это и есть продакшен-паттерн для больших кластеров. Важно: централизованное хранилище конфигурации - функция Enterprise Edition.
Кто назначает лидера (failover). Опция replication.failover задаёт режим:
  • off - все мастера фиксированы, ручное управление.
  • manual - лидер каждого реплика-сета прописан в конфиге руками (через replicaset.leader).
  • election - встроенные выборы на базе Raft: узлы сами выбирают лидера по кворуму. Обычно идёт в паре с синхронной репликацией.
  • supervised - внешний координатор (официальный failover coordinator) читает конфигурацию из etcd, опрашивает инстансы и назначает лидера по их здоровью.
Синхронная репликация. Отдельная подсистема: транзакция в синхронном спейсе считается зафиксированной только после подтверждения большинством (replication.synchro_quorum). Это даёт защиту от потери данных при failover, но добавляет латентность на запись. Выборы и синхронность - независимые механизмы, их можно включать по отдельности.

Docker. Официальный образ tarantool/tarantool содержит бинарь и популярные модули. В продакшене обычно: монтируем каталог с конфигом и кодом приложения внутрь контейнера, прокидываем порты iproto и HTTP-метрик, кладём снапшоты и WAL на персистентный volume (потеря volume = потеря данных). Внутри контейнера инстанс запускается через tt или напрямую tarantool с указанием своего имени.

Изображение
Продакшен-топология кластера Tarantool 3.x

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

Скелет config.yaml (топология двух реплика-сетов с выборами):

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

credentials:
  users:
    replicator:
      password: 'topsecret'
      roles: [ replication ]

iproto:
  advertise:
    peer:
      login: replicator

replication:
  failover: election          # выборы на базе Raft
  synchro_quorum: 2           # кворум для синхронной записи

groups:
  storages:
    replicasets:
      storage-a:
        instances:
          storage-a-001: { iproto: { listen: [{uri: '127.0.0.1:3301'}] } }
          storage-a-002: { iproto: { listen: [{uri: '127.0.0.1:3302'}] } }
      storage-b:
        instances:
          storage-b-001: { iproto: { listen: [{uri: '127.0.0.1:3303'}] } }
          storage-b-002: { iproto: { listen: [{uri: '127.0.0.1:3304'}] } }
config.yaml, который тянет топологию из etcd (продакшен-паттерн):

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

config:
  etcd:
    endpoints:
      - http://etcd-1:2379
      - http://etcd-2:2379
      - http://etcd-3:2379
    prefix: /myapp
    http:
      request:
        timeout: 3
Запуск и проверка через tt:

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

$ tt start cluster
$ tt status cluster
INSTANCE              STATUS   PID   MODE  CONFIG  BOX      UPSTREAM
cluster:instance-001  RUNNING  8747  RW    ready   running  --
cluster:instance-002  RUNNING  8748  RO    ready   running  --
cluster:instance-003  RUNNING  8749  RO    ready   running  --
Запуск официального образа в Docker:

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

$ docker run --name td -d \
    -p 3301:3301 -p 8081:8081 \
    -v /srv/myapp/cfg:/opt/tarantool \
    -v /srv/myapp/data:/var/lib/tarantool \
    tarantool/tarantool:3
Сравнение режимов failover:

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

режим        кто решает          кворум   когда применять
-----------  ------------------  -------  -----------------------
off          оператор вручную    нет      статичные мастера
manual       конфиг (leader:)    нет      простые, ручной контроль
election     сами узлы (Raft)    да       авто-failover + синхрон
supervised   внешний координатор да       контроль из etcd/TCM
Частые заблуждения и грабли
  • Кластер из двух узлов. Кажется отказоустойчивым, но кворум 2 из 2 недостижим при разрыве - запись встаёт. Нужно минимум три узла (или три участника выборов).
  • election без синхронной репликации. Авто-выборы сами по себе почти не защищают данные: новый лидер может оказаться без последних транзакций. Защита появляется только вместе с синхронной репликацией.
  • Redo, а не undo. У Tarantool журнал на повтор, отката нет. Если после выборов реплика оказалась впереди нового лидера, её удаляют и перекачивают данные заново. Это нормальное, но болезненное поведение - не пугайтесь.
  • Зависшая синхро-очередь. При смене лидера незавершённые синхронные транзакции прошлого мастера могут потребовать ручного box.ctl.promote() или очистки очереди. Закладывайте это в runbook.
  • Volume в Docker. Снапшоты и WAL внутри контейнера без внешнего volume исчезают при пересоздании контейнера. Это самая частая потеря данных у новичков.
  • Закрытый full-mesh. Забыли открыть iproto-порты между всеми узлами реплика-сета - репликация молча не поднимается. Mesh требует связности каждый-с-каждым.
  • Пароли в YAML. Официально не рекомендуется хранить пароли открытым текстом - грузите их из переменных окружения или внешних файлов.
Мини-лаба

Задание: соберите локально кластер из трёх инстансов в одном реплика-сете с режимом replication.failover: election.
  • Выполните tt init, создайте каталог instances.enabled/cluster.
  • В instances.yml перечислите три инстанса, в config.yaml опишите один реплика-сет с тремя instances и опцией failover: election.
  • Запустите tt start cluster и tt status cluster - убедитесь, что один инстанс в режиме RW, два в RO.
  • Подключитесь к лидеру (tt connect), создайте спейс, запишите тапл, прочитайте его на реплике.
  • Остановите лидера (tt stop одного инстанса) и через tt status посмотрите, как RW-роль переехала на другой узел.
Контрольные вопросы
  • Почему официально требуется минимум три узла, и что произойдёт с записью в кластере из двух узлов при сетевом разрыве?
  • В чём разница между режимами failover election и supervised: кто в каждом случае принимает решение о лидере?
  • Зачем election почти бесполезен для сохранности данных без синхронной репликации?
  • Какие данные нужно вынести на персистентный Docker volume, чтобы не потерять состояние при пересоздании контейнера, и где в конфиге указываются адреса централизованного хранилища конфигурации?
👍4 ❤️3 🔥 😄 🤔1
Ответить
← Предыдущая глава
Обновления: схема, rolling upgrade
Следующая глава →
Администрирование через официальный TCM (Tarantool Cluster Manager)

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

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

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

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

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