Vitess — слой шардирования и маршрутизации поверх MySQL, который позволяет приложению работать с одним логическим кластером, пока данные разложены по шардам. Он не заменяет MySQL, а управляет соединениями, репликацией, схемами и переездами без остановки сервиса. Ниже — путь от локального стенда до VSchema и онлайн-перешардирования.

Когда MySQL нужен шардинг, а когда — нет

Сначала исчерпайте простые варианты: индексы, партиционирование, реплики для чтения, кэш и разделение сервисов по базам. Шардинг усложняет транзакции, JOIN и резервное копирование. Vitess оправдан, когда база перестала помещаться на узел, а рост записи требует горизонтального масштабирования. Если нагрузка читающая, часто достаточно реплик.

Заранее примите ограничения: кросс-шардовые транзакции в общем случае не поддерживаются, JOIN между шардами дорог, внешние ключи не работают между шардами. Приложение проектируется вокруг ключа шардирования, а не вокруг произвольных запросов.

Из чего состоит кластер Vitess

vtctld управляет метаданными и топологией, vtgate принимает подключения по протоколу MySQL и маршрутизирует запросы, vttablet стоит рядом с каждым MySQL, а vtorc следит за восстановлением. Топология хранится в etcd или Consul; для production нужен кворум из трёх узлов.

Ключевое пространство (keyspace) — логическая база, шард — её горизонтальная часть. Внутри шарда есть primary и реплики. Приложение подключается только к vtgate, поэтому смена primary или переезд шарда не требует правок в коде.

Быстрый стенд: vttestserver

Для знакомства не нужно собирать кластер вручную. Официальный образ vttestserver поднимает MySQL, vtgate и vttablet в одном контейнере. Это учебный стенд: данные и настройки не рассчитаны на production.

docker run --name vttestserver -p 33577:33577 -e PORT=33577 -e MYSQL_BIND_HOST=0.0.0.0 vitess/vttestserver:mysql80
mysql -h 127.0.0.1 -P 33577 -u root
SHOW DATABASES;

Порт 33577 здесь — MySQL-протокол vtgate. Если подключение не проходит, проверьте, что контейнер запущен и порт не занят. Для чистой работы удалите старый контейнер.

Ключевое пространство, шарды и VSchema

Сначала создайте unsharded-keyspace и перенесите текущую базу. Затем опишите шардированную версию в VSchema: какие таблицы шардируются, по какому столбцу и какой vindex используется. Для равномерного распределения подходит hash по высококардинальному ключу, например customer_id.

vtctldclient --server localhost:15999 CreateKeyspace commerce
vtctldclient --server localhost:15999 CreateShard --keyspace commerce --shard -
vtctldclient --server localhost:15999 GetTablets --keyspace commerce
vtctldclient --server localhost:15999 ApplyVSchema --vschema-file vschema.json commerce

VSchema задаёт отображение таблиц и порядок генерации идентификаторов. Если оставить MySQL AUTO_INCREMENT, на разных шардах появятся одинаковые значения — используйте последовательность Vitess.

{
  "sharded": true,
  "vindexes": {
    "hash": { "type": "hash" }
  },
  "tables": {
    "orders": {
      "column_vindexes": [
        { "column": "customer_id", "name": "hash" }
      ],
      "auto_increment": {
        "column": "id",
        "sequence": "orders_seq"
      }
    },
    "orders_seq": { "type": "sequence" }
  }
}

Схема, последовательности и онлайн-миграции

Таблицу последовательности держите в unsharded-keyspace, а в шардированном используйте через VSchema. Схему применяйте через vtctld, а не прямым ALTER на каждом tablet: так изменение пройдёт согласованно. Для больших таблиц включайте онлайн-стратегию DDL.

CREATE TABLE orders_seq (
  id BIGINT NOT NULL,
  next_id BIGINT NOT NULL,
  cache BIGINT NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;
INSERT INTO orders_seq (id, next_id, cache) VALUES (1, 1, 1000);

CREATE TABLE orders (
  id BIGINT NOT NULL,
  customer_id BIGINT NOT NULL,
  total DECIMAL(12,2) NOT NULL,
  created_at DATETIME NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

После применения схемы подключитесь к vtgate и проверьте маршрутизацию. SQL с customer_id должен уходить в нужный шард; запрос без ключа шардирования станет scatter-запросом по всем шардам.

vtctldclient --server localhost:15999 ApplySchema --sql-file schema.sql commerce
mysql -h 127.0.0.1 -P 15306 -u app -p
INSERT INTO orders (customer_id, total, created_at) VALUES (42, 199.90, NOW());
SELECT * FROM orders WHERE customer_id = 42;

Переезд без простоя: MoveTables и Reshard

Когда база уже работает, не переключайте приложение вручную. MoveTables переносит таблицы в целевую шардированную базу, копирует данные и держит изменения актуальными. Целевой keyspace и его шарды создайте заранее. Проверьте отставание, переключите трафик, затем завершите workflow. Для изменения числа шардов используйте Reshard.

vtctldclient MoveTables --workflow orders_sharded --source-keyspace commerce --target-keyspace commerce_sharded create
vtctldclient MoveTables --workflow orders_sharded --target-keyspace commerce_sharded SwitchTraffic
vtctldclient MoveTables --workflow orders_sharded --target-keyspace commerce_sharded Complete
vtctldclient Reshard --workflow split80 --target-keyspace commerce --source-shards - --target-shards -80,80- create

Перед SwitchTraffic прогоните read-only нагрузку на целевом keyspace, сравните число строк и проверьте отставание репликации. После переключения не удаляйте исходные данные: они нужны для отката и разбора расхождений.

Что ломается в production

  • Кросс-шардовые JOIN и транзакции: переписывайте запросы или используйте lookup-таблицы.
  • Горячий шард: ключ шардирования выбран неудачно; status или region с малым числом значений дадут перекос.
  • Дубликаты идентификаторов: забыта последовательность Vitess или остался MySQL auto_increment.
  • Прямой DDL на tablet: схема расходится между шардами; используйте ApplySchema и онлайн-стратегию.
  • Отставание реплик: проверяйте SHOW REPLICA STATUS на tablet и не отправляйте туда критичное чтение.
  • Шторм подключений: приложение открывает слишком много сессий к vtgate; ограничьте пул и используйте таймауты.

Диагностика

Начинайте с топологии: видит ли vtctld все tablet, в каком состоянии шарды и кто primary. Затем проверяйте маршрутизацию через vtgate и только потом MySQL.

vtctldclient GetKeyspaces
vtctldclient GetShards --keyspace commerce
vtctldclient GetTablets --keyspace commerce
mysql -h 127.0.0.1 -P 15306 -u app -p -e "SHOW VITESS_SHARDS"
mysql -h 127.0.0.1 -P 15306 -u app -p -e "SHOW VITESS_TABLETS"

Если запрос идёт не туда, проверьте VSchema и значение ключа. Если tablet не поднимается, смотрите его журнал и доступность MySQL. Если после переезда расходятся данные, сравните контрольные суммы по шардам и не завершайте workflow до устранения причины.

Чек-лист

  • Ключ шардирования выбран по нагрузке и обеспечивает равномерное распределение.
  • Все таблицы с автоинкрементом используют последовательности Vitess.
  • Кросс-шардовые запросы известны и осознанно ограничены.
  • Для каждого шарда настроены реплики, резервное копирование и мониторинг отставания.
  • Переезд проходит через MoveTables или Reshard, а не через ручное копирование.
  • Есть план отката и проверка целостности до завершения workflow.

Итог

Vitess решает задачу горизонтального масштабирования MySQL, но требует дисциплины в проектировании данных. Начните с локального стенда, затем перенесите базу в unsharded-keyspace и только после этого включайте шардирование. VSchema, последовательности и онлайн-переезды — три опоры, без которых кластер быстро превращается в набор несогласованных MySQL. Если нагрузка ещё позволяет реплики и оптимизацию запросов, не спешите с шардингом.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте