Deep Engineering

MEASUREMENT

bench/valkey-cluster/runs/discovery.txt

The script that produced the numbers in the article, and the record of the run. The file is read from the repository at build time — this is the code that was run, not a copy of it.

Cited in
/en/system-design/caching/valkey-clustering

The run below is recorded in Russian. It is a lab record, kept in the language it was written in; the numbers, the tables and the code read the same either way.

Record of the run

This measurement has no recorded run — only the script.

Script

118 lines
Valkey 9.1.2 · один хост, процессы на случайных портах
нативный кластер (6 узлов) и связка Sentinel (1 мастер + 2 реплики + 3 sentinel)

1. КЛАСТЕР ОТВЕЧАЕТ НЕ ДАННЫМИ, А АДРЕСОМ
----------------------------------------------------------------------
  CLUSTER KEYSLOT foo                         12182

  узел 44997 (мастер): SET foo 1              MOVED 12182 127.0.0.1:48711
  узел 53953 (мастер): SET foo 1              MOVED 12182 127.0.0.1:48711
  узел 48711 (мастер): SET foo 1              OK
  узел 39529 (реплика): SET foo 1             MOVED 12182 127.0.0.1:48711
  узел 54583 (реплика): SET foo 1             MOVED 12182 127.0.0.1:48711
  узел 51665 (реплика): SET foo 1             MOVED 12182 127.0.0.1:48711

  Пять узлов из шести ответили одинаково и не данными. MOVED — это не
  ошибка в обычном смысле: узел не отказал, а сказал, КУДА идти, и
  назвал слот. Клиент кластера на таком ответе чинит свою карту слотов
  и повторяет команду по названному адресу; «глупый» клиент, как
  здесь, просто видит текст.
  
  Адресация тут вообще не про узлы, а про слоты: ключ отображается в
  один из 16 384 слотов, а уже слот принадлежит узлу. Поэтому
  переезд данных между узлами не меняет ни одного ключа — меняет
  владельца слота.

2. В РЕЖИМЕ SENTINEL УЗЕЛ ДАННЫХ ПРО ТОПОЛОГИЮ НЕ ЗНАЕТ НИЧЕГО
----------------------------------------------------------------------
  узел данных 43471: CLUSTER INFO             ERR This instance has cluster support disabled
  узел данных 43471: роль                     master
  узел данных 50535: роль                     slave

  sentinel 50997: SENTINEL get-master-addr-by-name 127.0.0.1:43471
  sentinel 50997: сколько реплик знает        2
  sentinel 50997: сколько других sentinel знает 2

  sentinel 50997: CONFIG RESETSTAT            ERR unknown command 'config', with args beginning with: 'resetstat'

  Первая строка — весь ответ на вопрос «а нельзя ли спросить у самого
  узла». Нельзя: узел данных вне кластера про кластер не знает и
  честно об этом говорит. Он не знает и того, что за ним кто-то
  наблюдает: роль он покажет свою (master или slave), а вот кто
  мастер С ТОЧКИ ЗРЕНИЯ СИСТЕМЫ — вопрос не к нему.
  
  Отвечает на него отдельная служба, и она не хранит данных. Последняя
  строка показывает, насколько отдельная: у sentinel даже нет команды
  CONFIG. Это не урезанный узел, это другой набор команд на том же
  двоичном файле.

3. ЧТО ДЕЛАЕТ НАСТОЯЩИЙ КЛИЕНТ КЛАСТЕРА ЗА ОДНУ КОМАНДУ
----------------------------------------------------------------------
  клиенту дан один адрес из шести         127.0.0.1:51665
  окно наблюдения                         2 с, и столько же вхолостую для контроля

  узел                    вхолостую  с клиентом  что пришло за второе окно
  44997                           4           8  client|setinfo×2 command×1 hello×1 replconf×2
  53953                           4           4  replconf×2
  48711                           4           8  client|setinfo×2 hello×1 replconf×2 set×1
  39529                           2           2  
  54583                           2           2  
  51665 (адрес клиенту)           2           7  client|setinfo×2 cluster|slots×1 hello×1 set×1

  Считают сами узлы: это их счётчик обработанных команд. Контрольное
  окно вхолостую нужно потому, что узлы кластера всё время говорят друг
  с другом по шине; клиентское видно только на его фоне.
  
  Видно, что клиент сделал на самом деле: сходил к единственному
  известному адресу за картой слотов (cluster|slots) и уже по карте
  отправил запись туда, куда надо (set). Команды hello и
  client|setinfo — это клиент представляется; они к поиску узла
  отношения не имеют.
  
  Два лишних на первый взгляд следа стоит прочитать правильно. Пара
  replconf — это разговор мастера с его репликой, он идёт и без
  клиента. А select с set на ЕЩЁ ОДНОМ узле — это та же самая запись,
  доехавшая до реплики по репликации: клиент к этому узлу не
  подключался вовсе. Команды в счётчике узла — не обязательно команды
  от клиента, и здесь это видно прямо.
  
  Отсюда свойство, которое обычно и имеют в виду под «кластер сам
  разбирается»: знать все узлы клиенту не нужно, достаточно одного
  живого. Карту он получит от него и дальше будет ходить напрямую —
  посредника между клиентом и данными в этом режиме нет вообще.

4. ЧТО ДЕЛАЕТ НАСТОЯЩИЙ КЛИЕНТ SENTINEL ЗА ОДНУ КОМАНДУ
----------------------------------------------------------------------
  клиенту дан один sentinel и имя набора  127.0.0.1:50997 / cache
  окно наблюдения                         2 с, и столько же вхолостую для контроля

  узел                            вхолостую  с клиентом  что пришло за второе окно
  мастер 43471                           14          22  client|setinfo×2 hello×1 ping×6 publish×3 replconf×4 set×1
  реплика 50535                          14          19  ping×7 publish×6 set×1
  реплика 51415                          14          19  ping×7 publish×6 set×1
  sentinel 50997 (адрес клиенту)          8          11  
  sentinel 37267                          8           8  
  sentinel 44483                          7           8  

  Порядок обратный третьему блоку: сначала вопрос СЛУЖБЕ, потом
  команда данным. Узел данных не участвовал в поиске самого себя и не
  мог бы: у него для этого нет ни команды, ни сведений.
  
  Фон здесь заметнее, чем в кластере, и в нём же видно устройство
  службы. Sentinel непрерывно опрашивает данные (ping) — отсюда
  колонка «вхолостую». А publish на узлах ДАННЫХ — это как раз то, чем
  sentinel находит других sentinel: они публикуют себя в канал самого
  узла и там же друг друга слышат. Отдельного реестра у них нет;
  общая точка встречи — наблюдаемый узел.
  
  Имён команд у sentinel нет ни в одной колонке по той же причине, что
  и CONFIG в блоке 2: у него нет commandstats, только общий счётчик.
  
  Практическое следствие, которое из этого растёт: в режиме Sentinel
  клиент обязан ходить через библиотеку, умеющую sentinel, и держать
  адреса sentinel в конфиге. Если он подключится прямо к адресу
  данных — он будет работать ровно до первого переключения, а потом
  молча начнёт писать не туда. Что именно при этом происходит, видно
  в блоке про возвращение старого мастера.