помещение
Недавно автор использовал его при работе над проектомRedis
Хранит список заказов, отображаемый клиентом. Список должен быть разбит на страницы. Поскольку автор ранееRedis
Сценарии использования различных типов данных не очень знакомы, так что я вижуHash
тип:
USER_ID:1
ORDER_ID:ORDER_XX: {"amount": "100","orderId":"ORDER_XX"}
ORDER_ID:ORDER_YY: {"amount": "200","orderId":"ORDER_YY"}
ЧувствоватьHash
Сценарии, где тип полностью соответствует требованиям. Тогда считайте само собой разумеющимся, чтобы рассмотреть возможность использованияHSCAN
Команда разбита на страницы, что вызывает проблемы, возникающие позже.
Команды SCAN и HSCAN
SCAN
Команда выглядит следующим образом:
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
// 返回值如下:
// 1. cursor,数值类型,下一轮的起始游标值,0代表遍历结束
// 2. 遍历的结果集合,列表
SCAN
командоватьRedis
Добавлено в версии 2.8.0, временная сложность рассчитывается следующим образом: Временная сложность каждого раунда обхода равнаO(1)
, обходятся все элементы до тех пор, пока курсорcursor
Временная сложность возврата 0 равнаO(N)
,вN
количество элементов в коллекции.SCAN
для всегоDatabase
Последовательный обход всех ключей внутри, он не будет блокироватьсяRedis
, то есть использоватьSCAN
Производительность команды, проходящей через KEY, будет лучше, чемKEY *
Заказ. заHash
тип имеет производную командуHSCAN
посвященный обходуHash
Тип и связанные с ним свойства (Field
) поля:
HSCAN key cursor [MATCH pattern] [COUNT count]
// 返回值如下:
// 1. cursor,数值类型,下一轮的起始游标值,0代表遍历结束
// 2. 遍历的结果集合,是一个映射
Автор в свое время не проверял подробноRedis
Официальная документация, считать само собой разумеющимся, чтоHash
Тип разбиения по страницам прост:
// 第一页
HSCAN USER_ID:1 0 COUNT 1 <= 这里认为返回的游标值为1
// 第二页
HSCAN USER_ID:1 1 COUNT 1 <= 这里认为返回的游标值为0,结束迭代
На самом деле результат выполнения таков:
HSCAN USER_ID:1 0 COUNT 1
// 结果
0
ORDER_ID:ORDER_XX
{"amount": "100","orderId":"ORDER_XX"}
ORDER_ID:ORDER_YY
{"amount": "200","orderId":"ORDER_YY"}
То есть в первом раунде обхода все соответствующие KEYField-Value
вернулся в полном объеме. Автор пытался увеличить хэш set KEY=USER_ID:1
элементы внутри, но когда объем данных относительно велик, это все равно не дает ожидаемого эффекта разбиения по страницам; с другой стороны, попробуйте изменитьCOUNT
значение, найденное в любом случае для измененияCOUNT
Ни одно из значений не влияет на результат обхода (то есть все результаты возвращаются в первой итерации). В случае недоумения вы можете только внимательно прочитать официальную документацию, чтобы найти решение. существуетSCAN
командаCOUNT
Причина указана в описании объекта:
Простой перевод для понимания:
SCAN
команда и ее производные не гарантируют количество элементов, возвращаемых за итерацию, но могут использоватьCOUNT
Атрибуты настраиваются по опытуSCAN
поведение команды.COUNT
Определяет количество элементов, которые должны быть пройдены за один вызов, чтобы упростить прохождение коллекции, по сути просто значение подсказки.
-
COUNT
Значение по умолчанию — 10. - при обходе цели
Set
,Hash
,Sorted Set
илиKey
Пространство достаточно велико, чтобы его можно было представить с помощью хеш-таблицы, и оно не используетMATCH
На основании свойств,Redis
Сервер вернетсяCOUNT
или чемCOUNT
Большой результирующий набор элементов обхода. - При обходе содержит только
Integer
стоило тогоSet
сборник (также известный какintsets
),илиziplists
кодированный типHash
илиSorted Set
множества (указывая на то, что пространство, занимаемое элементами в этих множествах, достаточно мало), тоSCAN
Команда вернет все элементы в коллекции, игнорируя ее напрямуюCOUNT
Атрибуты.
Обратите внимание на пункт 3, это вHash
используется в коллекцияхHSCAN
ЗаказCOUNT
Основная причина отказа собственности.Redis
Есть два иHash
типziplist
Соответствующие значения конфигурации для кодирования:
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
Когда выполняется одно из следующих двух условий,Hash
Кодировка коллекции будет заданаziplist
превратится вdict
:
- когда
Hash
элементы данных в коллекции (т.е.Field-Value
справа), когда число превышает 512. - когда
Hash
любой вставленный в коллекциюField-Value
правильноValue
Длина превышает 64.
когдаHash
Кодировка коллекции будет заданаziplist
превратится вdict
,Redis
заHash
Оптимизация использования пространства памяти типа эквивалентна неудаче, и она понижена до кодировки словарного типа, которая потребляет больше памяти.HSCAN
ЗаказCOUNT
свойства вступят в силу.
Верификация случая
Чтобы просто проверить выводы, сделанные в предыдущем разделе, напишите тестовые данные следующим образом:
// 70个X
HSET USER_ID:2 ORDER_ID:ORDER_XXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// 70个Y
HSET USER_ID:2 ORDER_ID:ORDER_YYY YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
Затем приступайте к тестированиюHSCAN
Заказ:
// 查看编码
object encoding USER_ID:2
// 编码结果
hashtable
// 第一轮迭代
HSCAN USER_ID:2 0 COUNT 1
// 第一轮迭代返回结果
2
ORDER_ID:ORDER_YYY
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
// 第二轮迭代
HSCAN USER_ID:2 2 COUNT 1
0
ORDER_ID:ORDER_XXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
В тестовом примере длина двух значений намеренно установлена равной 70, что больше 64, то есть пустьHash
Коллекция превращается вdict(hashtable)
тип такой, чтоCOUNT
свойства вступают в силу. Однако такой подход заключается в отказе отRedis
заHash
Оптимизация памяти для коллекций. Очевидно,HSCAN
Команды естественно рассчитаны не на листание данных, а на пошаговую итерацию (т.е. если итерируемая коллекция большая, то не заблокируетRedis
Служить). Так что я, наконец, отказался от использованияHSCAN
команда для поиска других инструментов, более подходящих для запросов на подкачку данныхRedis
Заказ.
резюме
Через этот простой случай наступления на яму автор приобрел некоторый опыт:
- Не будьте предвзятыми и используйте промежуточное ПО в сочетании с реальной сценой.
- Перед использованием инструмента внимательно прочтите руководство по эксплуатации.
- Проверьте свои предположения или выведенные результаты на некоторых случаях.
Redis
Предоставляемый API очень богат, и в будущем должно быть больше опыта хождения по яме.
Приложение
- Страница на гитхабе:Woohoo.throwable.club/2019/08/12/…
- Кодовая страница:кинутьable.coding.what/2019/08/12/…
- Файл уценки:GitHub.com/Zhaojun из розетки жирным шрифтом/Нет...
(Конец этой статьи e-a-20190812 c-1-d)
Технический публичный аккаунт ("Throwable Digest"), который время от времени выкладывает оригинальные технические статьи автора (никогда не занимайтесь плагиатом и не перепечатывайте):
Развлекательный публичный аккаунт («Скульптуры из песка каждый день») выбирает интересные фотографии, тексты и видео о скульптурах из песка, чтобы время от времени публиковать их, чтобы облегчить жизнь и работу: