Какие команды Redis не работают в кластерном режиме?

ОБНОВЛЕНИЕ – 2023 – Verx Redis теперь поддерживает сканирование, но есть ошибка, см. https://github.com/vert-x3/vertx-redis-client/issues/345 .

Моя команда некоторое время использовала клиент Redis Vertx икоманду keys с кластером Redis, и меня попросили провести рефакторинг, чтобы вместо этого использовать команду сканирования , поскольку «ключи» не предназначены для производства.

Когда я начал использовать сканирование, я получил от клиента сообщение об ошибке: «Сканирование не поддерживается — используйте клиент, не являющийся кластером, на правильном узле». Таким образом, клиент Vertx Redis поддерживает «ключи» всего кластера, но не «сканирование». Я узнал, что я должен создать 1 клиента на узел, если я хочу выполнить «сканирование» всего кластера, например, что-то вроде этого, но это кажется слишком сложным и малоэффективным выбором (или я могу использовать «хэш-теги», которые не будет работать для моего варианта использования).

Я пытаюсь выяснить, какие команды поддерживаются для всего кластера, а какие нет (чтобы мы не совершили еще одну ошибку, подобную этой), и единственная подсказка, которую я вижу, находится в спецификации кластера Redis:

Redis Cluster реализует все одноклавишные команды, доступные в нераспределенной версии Redis.

Мой вопрос: что такое команда с одним ключом?

Или другое объяснение, которое я увидел здесь, было следующим:

Единственное различие между распределенными и нераспределенными клиентами Redis заключается в том, что в распределенном случае MOVED и ASKS будут «отслеживаться».

Я также не понимаю, как следуют MOVED или ASK - я предполагаю, что это просто означает, что клиент повторно подключается к правильному узлу и пытается снова? Это кажется ужасно неэффективным, как обсуждалось здесь.

Также странно, что в документации клиента Vertx не упоминается ни этот, ни более популярный клиент Jedis.

Я пропустил какую-то ключевую документацию, которая объясняет все это?

3 ответа

Поскольку на мой первоначальный вопрос не ответили, позвольте мне попробовать после дальнейших исследований:

Какие команды Redis не работают в кластерном режиме?

Нет — все некластеризованные команды будут выполняться и в каком-то смысле «работать» в кластере.

Где документация, разъясняющая, как разные команды работают в кластере и в автономном режиме?

Это здесь:

https://redis.io/docs/reference/command-tips/#request_policyhttps://redis.io/docs/reference/command-tips/#response_policy

По сути, есть 3 варианта запуска команды для кластера.

  1. Выполнить его на случайном узле
  2. Выполнить на всех узлах
  3. «Особый» нетривиальный случай

Какие команды Redis могут запутать разработчиков при выполнении в кластере?

Единственная команда, которая ведет себя особенно запутанно, это SCAN. Вот почему это единственная команда, которая помечается как ["request_policy:special" Redis][1]

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

Проблема со сканированием кластера заключается в том, что нет смысла выполнять его только на одном узле или на всех узлах, поэтому это особый случай. Причина в том, что SCAN возвращает курсор, и вам может потребоваться разное количество итераций на каждом узле. Например, у вас может быть широкомасштабное сканирование кластера, для которого требуется 1 сканирование на NODEA и 3 сканирования на NODEB.

Мой вопрос: что такое команда с одним ключом?

Это команда, которая имеет единственный ключ a в качестве параметра. Например,SET key value, устанавливает только один ключ.

На самом деле вы пропустили второе предложение: Команды, выполняющие сложные операции с несколькими ключами... реализованы для случаев, когда все ключи... хешируются в один и тот же слот . Так что еслиk1,k2иk3расположены в одном хеш-слоте, вы можете отправитьMGET k1 k2 k3команду для кластера Redis.

Я предполагаю, что это просто означает, что клиент повторно подключается к правильному узлу и пытается снова?

ДА.

Это кажется ужасно неэффективным, как обсуждалось здесь.

Приличный клиент Redis должен кэшировать сопоставление слот-узел. Таким образом, если сопоставление слот-узел не изменилось, клиенты могут вычислить правильный слот/узел на основе ключа и отправить команду на правильный узел. Так что он может избежать перенаправления.

Чтобы понять, почему сканирование не было реализовано в Vert.x Redis Cluster Client, нам сначала нужно узнать, как работает команда SCAN. СКАНИРОВАНИЕ Redis

В автономном режиме вы, например, сканируете все ключи, соответствующие шаблону на узле. В соответствии с документацией мы инициируем первый вызов с помощьюSCAN 0 MATCH *11*где 0 - начальный курсор. В результате мы бы получили что-то вроде этого:

      1) "288"
2) 1) "key:911"
   2) "key:811"
   3) "4511"
   4) "some11key"

После этого результата вы вызовете следующий SCAN с возвращенным курсором, напримерSCAN 288 MATCH *11*и так далее, пока вы не получите возвращенный курсор 0. Таким образом, на автономном сервере Redis вы, вероятно, будете многократно вызывать команду SCAN в цикле while, скорее всего, до тех пор, пока не получите ответ с курсором 0, который отмечает конец SCAN.

Реализация этого на клиенте кластера практически невозможна, так как клиенту нужно будет инициировать команду на всех узлах с разными хеш-слотами и возвращать вам множественный ответ, уникальный для каждого узла. После этого невозможно продолжить, так как вы получите разные курсоры для каждого узла. Таким образом, клиенту нужно будет выполнить некоторую фоновую магию и сохранить состояние, чтобы продолжить. Таким образом, это не ограничение Vert.x Redis Client, а скорее ограничение работы команды SCAN. Единственный обходной путь — выполнить команду полностью от начала до конца для каждого отдельного узла вручную.

Мой вопрос: что такое команда с одним ключом?

Одноклавишные команды — это команды, которые работают только с одной клавишей. Это делается для того, чтобы перестраховаться и сказать, что команды, которые работают только на одном узле, будут на 100% работать из коробки без какой-либо специальной клиентской реализации. Это не мешает клиентским реализациям выполнять некоторую дополнительную работу, чтобы заставить многоклавишные команды работать, например, команду KEYS. Вы можете увидеть этот пример и еще несколько команд, которые были реализованы для работы с Redis Cluster, хотя они являются командами с несколькими клавишами. Реализация KEYS Клиент Vert.x Redis Cluster

Я также не понимаю, как следует MOVED или ASK

Когда по какой-либо причине изменяется топология кластера, клиент, скорее всего, останется с неверным статусом хеш-слота. Поэтому, если вы инициируете команду на клиенте кластера с неверными данными хеш-слота, он попытается отправить запрос на неправильный сервер. В этом случае сервер ответит ответом MOVE/ASK, и клиент должен следовать ему, чтобы отправить команду правильному серверу. Кроме того, из-за производительности разумно обновлять хэш-данные клиента, чтобы мы снова не отправляли команды на неправильный сервер. И именно так реализован Vert.x Redis Client. Некоторые другие клиенты также имеют фоновую периодическую проверку, чтобы обновлять данные хеш-слота. Это одна из функций, запланированных для Vert.x Redis Cluster Client.

Другие вопросы по тегам