Какие команды 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 варианта запуска команды для кластера.
- Выполнить его на случайном узле
- Выполнить на всех узлах
- «Особый» нетривиальный случай
Какие команды 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.