Битва Redis | Подробное объяснение 5 типов данных Redis

Java Redis

Это 14-й день моего участия в августовском испытании обновлений. Ознакомьтесь с подробностями мероприятия: Испытание августовского обновления

В настоящее время Redis является очень популярной базой данных KV. Она известна своими высокопроизводительными возможностями чтения и записи. На самом деле, есть еще одно преимущество, заключающееся в том, что Redis предоставляет более распространенные типы данных, что делает Redis более широким диапазоном сценариев использования. Какие типы данных Redis предоставляет пользователям?В основном включают в себя: string (строка), List (список), Set (набор), Hash (хеш), Zset (упорядоченный набор), HyperLogLogs (структура данных для расчета кардинальности), Streams (Redis 5.0 предоставляет новую структуру данных для журнал моделирования).

Следует отметить, что упомянутый здесь тип данных относится к типу данных значения Redis, а тип ключа Redis всегда является строкой.

В этой статье в основном объясняются первые 5, которые являются 5 наиболее часто используемыми типами данных. Остальные два можно найти на официальном сайте Redis (redis.io), чтобы узнать для себя. Кроме того, Redis уже обязателен к просмотру на собеседованиях с Java-программистами, и“Redis有哪些数据类型?”Это также основной вопрос, который задает интервьюер, когда открывает рот. Если вы не можете пройти даже этот первый вопрос, то в принципе Redis уже крут.

строка | строковый тип

Строковый тип Redis может хранить строки, целые числа или числа с плавающей запятой. Если хранится целое число или число с плавающей запятой, он также может выполнять операции автоматического увеличения или автоматического уменьшения.

иСтроковый тип Redis безопасен для двоичного кода., который может содержать любые данные, такие как сериализованный объект, поток байтов изображения и т. д. Однако размер хранилища ограничен -512M.

Вот объяснение смысла бинарной безопасности: короче говоря, строка не анализируется в соответствии со специальным флагом (\0 на языке C), независимо от того, какой ввод, вывод всегда гарантированно будет исходным обработанным вводом. а не по какому-то специальному формату.

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

Ответ — Sds (простая динамическая строка), Redis определяет свою собственную структуру данных внизу. (Легко понять)

typedef char *sds;

struct sdshdr {

    // buf 已占用长度
    int len;

    // buf 剩余可用长度
    int free;

    // 实际保存字符串数据的地方
    char buf[];
};

Некоторые команды для работы со строками

Базовый набор, команды get, del и примеры

get keynameПолучить значение, хранящееся в данном ключе
set keyname valueУстановите для сохранения значения в данном ключе
del keynameудалить значение, хранящееся в данном ключе (общая команда, работает для всех типов)

127.0.0.1:6379> set happy today
OK
127.0.0.1:6379> get happy
"today"
127.0.0.1:6379> del happy
(integer) 1
127.0.0.1:6379> get happy
(nil)
127.0.0.1:6379>

Команды увеличения и уменьшения

incr keynameУвеличьте значение, хранящееся в ключе, на 1
decr kenameСохраненный ключ минус 1
incrby keyname amountДобавьте значение, сохраненное ключом, к целочисленной сумме
decrby keyname amountВычесть целое число из значения, сохраненного ключом
incrbyfloat keyname amountДобавьте значение, хранящееся в ключе, к сумме с плавающей запятой

127.0.0.1:6379> set number 1
OK
127.0.0.1:6379> get number
"1"
127.0.0.1:6379> incr number
(integer) 2
127.0.0.1:6379> get number
"2"
127.0.0.1:6379> decr number
(integer) 1
127.0.0.1:6379> get number
"1"
127.0.0.1:6379> incrby number 3
(integer) 4
127.0.0.1:6379> get number
"4"
127.0.0.1:6379> decrby number 2
(integer) 2
127.0.0.1:6379> get number
"2"
127.0.0.1:6379> incrbyfloat number 1.23
"3.23"
127.0.0.1:6379> get number
"3.23"

Подстрока и двоичные битовые команды

append keyname valueДобавить значение в конец указанной строки
getrange keyname start endПолучить подстроку всех символов в диапазоне от начала до конца, включая начало и конец
setrange keyname offset valueНачиная со смещения offset, используйте параметр value, чтобы перезаписать строковое значение, хранящееся в ключевом имени ключа.
getbit keyname offsetДля строкового значения, хранящегося в имени ключа, получите бит по указанному смещению.
setbit keyname offset valueУстанавливает или очищает бит по указанному смещению для строкового значения, хранящегося в имени ключа.

Обратите внимание, что индекс Redis начинается с 0

127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> append hello ,java
(integer) 10
127.0.0.1:6379> get hello
"world,java"
127.0.0.1:6379> getrange hello 2 5
"rld,"
127.0.0.1:6379> setrange hello 6 redis
(integer) 11
127.0.0.1:6379> get hello
"world,redis"
127.0.0.1:6379> 
127.0.0.1:6379> setbit bitstr 100 1
(integer) 0
127.0.0.1:6379> getbit bitstr 100
(integer) 1
127.0.0.1:6379> get bitstr
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b"
127.0.0.1:6379>

Несколько других важных команд

setnx key valueТолько если ключ key не существует, установите значение ключа key равным value; если ключ key уже существует, команда SETNX ничего не делает.
setex key seconds valueУстановите значение ключевого ключа в значение и установите время жизни для ключевого ключа в секундах. Если ключевой ключ уже существует, команда SETEX перезапишет существующее значение.

Для уточнения: - SETNX является сокращением от "SET if Not eXists" (если он не существует, то SET). Команда возвращает 1, если настройка выполнена успешно, и 0, если настройка не удалась. - Команда SETEX эквивалентна значению ключа SET и секундам ключа EXPIRE # Установите эффект двух команд, но SETEX является атомарной операцией.

127.0.0.1:6379> exists mark
(integer) 0
127.0.0.1:6379> setnx mark abcd
(integer) 1
127.0.0.1:6379> setnx mark defg
(integer) 0
127.0.0.1:6379> get mark
"abcd"
127.0.0.1:6379> setex cachekey 20 ak98
OK
127.0.0.1:6379> get cachekey
"ak98"
127.0.0.1:6379> ttl cachekey
(integer) 2

Список|Тип списка

Типы списков в Redis аналогичны типам списков во многих языках программирования.可以有序地存储多个字符串.

Поддерживает нажатие или извлечение элементов из левого и правого концов списка. Базовая реализация списка Redis представляет собой сжатый список (структура данных, реализуемая самим содержимым Redis) и двусторонний связанный список. см. картинку ниже

 

image.png

Изображение взято из «Redis Design and Introduction».

Команда работы с подробным списком

lpush key value [value...]

Вставьте одно или несколько значений в заголовок списка. Если ключ не существует, создается пустой список и выполняется операция LPUSH. Возвращает ошибку, если ключ существует, но не является типом списка.

После выполнения команды LPUSH возвращается длина списка.

127.0.0.1:6379> lpush listkey a
(integer) 1
127.0.0.1:6379> lpush listkey a b c
(integer) 4
127.0.0.1:6379> lrange listkey 0 -1
1) "c"
2) "b"
3) "a"
4) "a"
127.0.0.1:6379>
  • Тип списка может добавлять повторяющиеся элементы, что отличается от набора (типа коллекции), который будет описан позже.
  • lrange listkey 0 -1 — получить содержимое всего списка
  • Точно так же команда rpush добавляет элементы из правого конца списка.

LPOP key

Извлеките значение из левого конца списка и верните извлеченное значение

127.0.0.1:6379> lrange listkey 0 -1
1) "c"
2) "b"
3) "a"
4) "a"
127.0.0.1:6379> lpop listkey
"c"
127.0.0.1:6379> lrange listkey 0 -1
1) "b"
2) "a"
3) "a"
127.0.0.1:6379>

lrange key start end

Получить все значения элементов ключа списка в заданном диапазоне от начала до конца.

0 означает первый элемент, -1 означает последний элемент.

127.0.0.1:6379> lrange listkey 0 -1
1) "b"
2) "a"
3) "a"
127.0.0.1:6379> lrange listkey 0 1
1) "b"
2) "a"
127.0.0.1:6379>

lindex key index

Получить значение одного элемента списка в заданной позиции индекса.

Может быть -1 для последнего элемента, -2 для предпоследнего элемента и так далее.

127.0.0.1:6379> lrange listkey 0 -1
1) "b"
2) "a"
3) "a"
127.0.0.1:6379> lindex listkey 0
"b"
127.0.0.1:6379> lindex listkey -1
"a"
127.0.0.1:6379> lindex listkey 3
(nil)
127.0.0.1:6379>

blpop key [key …] timeout

blpop — это блокирующая команда pop, представляющая собой блокирующую версию ключевой команды lpop. Когда в данном списке нет элементов для извлечения, соединение будет заблокировано командой blpop до тех пор, пока не истечет время ожидания или не будет найден элемент для извлечения.

Когда задано несколько ключевых параметров, каждый список проверяется в порядке ключей параметров, и извлекается головной элемент первого непустого списка.

Следовательно, это можно обсудить в двух случаях: во-первых, если хотя бы один ключ существует и является непустым списком, команда blpop не будет блокироваться, а во-вторых, список в команде blpop является пустым списком, который будет заблокирован в течение периода ожидания.

Давайте сначала рассмотрим неблокирующий сценарий.Возвращаемое значение — это имя первого непустого списка и извлеченный элемент.

127.0.0.1:6379> lpush list1 hello java
(integer) 2
127.0.0.1:6379> lpush list2 hello redis
(integer) 2
127.0.0.1:6379> blpop list2 list1 list3 0
1) "list2"
2) "redis"
127.0.0.1:6379>

В сценарии блокировки он всегда будет блокироваться после выполнения команды blpop book1 book2 300.

127.0.0.1:6379> exists book1
(integer) 0
127.0.0.1:6379> exists book2
(integer) 0
127.0.0.1:6379> blpop book1 book2 300
阻塞在这里了

В это время, если мы открываем другой клиент Redis, выполнение выглядит следующим образомlpushКоманда помещает элемент в список book1.

127.0.0.1:6379> lpush book1 springboot
(integer) 1
127.0.0.1:6379>

В этот момент вернитесь к первоначально заблокированному клиенту, и элемент будет извлечен.

127.0.0.1:6379> exists book1
(integer) 0
127.0.0.1:6379> exists book2
(integer) 0
127.0.0.1:6379> blpop book1 book2 300
1) "book1"
2) "springboot"
(237.45s)
127.0.0.1:6379>

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

набор | тип коллекции

Коллекции Redis хранят несколько отдельных элементов неупорядоченным образом. Здесь следует отметить беспорядок и различие.

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

Обзор низкоуровневой реализации

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

 

image.png

 

Вот примерно объяснил字典: Фактически он состоит из набора пар ключ-значение.Ключи каждой пары ключ-значение разные.Программа может добавлять в словарь новые пары ключ-значение,или выполнять такие операции как поиск,обновление или удаление на основе на ключ. .

Когда набор (коллекция) Redis использует структуру данных словаря для сохранения данных, он сохраняет элементы в ключи словаря, а значение словаря единообразно устанавливается равным NULL .

Подробное объяснение команд работы с набором типов

sadd key member [member...]

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

srem key member [member...]

Удаляет один или несколько элементов из коллекции, несуществующие элементы игнорируются. Возвращает количество успешно удаленных элементов.

sismember key meber

Проверяет, существует ли член элемента в заданном ключе. Возвращает 1, если он есть, возвращает 0, если нет или ключ не существует.

scard keyВозвращает количество элементов, содержащихся в коллекции
spop keyСлучайным образом удаляет элемент из коллекции и возвращает удаленный элемент.
smembers keyВозвращает все элементы, содержащиеся в коллекции

127.0.0.1:6379> sadd set1 java spring redis
(integer) 3
127.0.0.1:6379> smembers set1
1) "redis"
2) "spring"
3) "java"
127.0.0.1:6379> scard set1
(integer) 3
127.0.0.1:6379> srem set1 spring
(integer) 1
127.0.0.1:6379> sismember set1 spring
(integer) 0
127.0.0.1:6379> smembers set1
1) "redis"
2) "java"
127.0.0.1:6379> sadd set1 mysql spring
(integer) 2
127.0.0.1:6379> spop set1
"redis"
127.0.0.1:6379> smembers set1
1) "mysql"
2) "spring"
3) "java"
127.0.0.1:6379>

Вот несколько команд для работы с несколькими коллекциями

sdiff key [key...]Возвращает элементы, которые существуют в первом наборе, но отсутствуют в других наборах (операция математической разности)
sinter key [key...]Возвращает элементы, присутствующие во всех множествах одновременно (математическая операция пересечения).sunion key [key...]Возвращает элементы, которые существуют хотя бы в одном наборе (математическом объединении)

127.0.0.1:6379> smembers set1
1) "mysql"
2) "spring"
3) "java"
127.0.0.1:6379> smembers set2
1) "mysql"
2) "springboot"
3) "redis"
127.0.0.1:6379> sdiff set1 set2
1) "java"
2) "spring"
127.0.0.1:6379> sinter set1 set2
1) "mysql"
127.0.0.1:6379> sunion set1 set2
1) "mysql"
2) "springboot"
3) "java"
4) "spring"
5) "redis"
127.0.0.1:6379>

hash | хеш-таблица (хеш-таблица)

Хэш-тип Redis на самом деле является уменьшенной версией Redis. Он хранит пары ключ-значение и хранит несколько пар ключ-значение в ключе Redis.

Обзор низкоуровневой реализации

Нижний слой хеш-типа в основном реализуется на основе структуры данных словаря.

 

image.pngВнутри Redis использует две структуры данных при реализации хеш-типа данных. При создании пустой хеш-таблицы по умолчанию используется структура данных ziplist, которая будет преобразована в словарную форму после выполнения определенных условий.

Подробное объяснение команд работы с хэш-таблицей

hmget hash-key key [key...]Получить значение одного или нескольких ключей из хэш-таблицы
hmset hash-key key value [key value...]Установить значения для одного или нескольких ключей в хеш-таблицеhdel hash-key key [key...]Удалить одну или несколько пар ключ-значение в хэш-таблице и вернуть количество успешно удаленных пар ключ-значение.
hlen hash-keyВозвращает количество пар ключ-значение, содержащихся в хэш-таблице.
hexists hash-key keyПроверить, существует ли данный ключ в хеш-таблице
hkeys hash-keyПолучить все ключи, содержащиеся в хеше
hvals hash-keyПолучить все значения, содержащиеся в хеше
hgetall hash-keyПолучить все пары ключ-значение, содержащиеся в хэше

127.0.0.1:6379> hmset hash1 username tom email 123@123 year 12
OK
127.0.0.1:6379> hmget hash1 email
1) "123@123"
127.0.0.1:6379> hlen hash1
(integer) 3
127.0.0.1:6379> hdel hash1 year
(integer) 1
127.0.0.1:6379> hexists hash1 year
(integer) 0
127.0.0.1:6379> hkeys hash1
1) "username"
2) "email"
127.0.0.1:6379> hvals hash1
1) "tom"
2) "123@123"
127.0.0.1:6379> hgetall hash1
1) "username"
2) "tom"
3) "email"
4) "123@123"
127.0.0.1:6379>

zset | отсортированный набор

По сравнению с набором, упорядоченный набор имеет два слова порядка. Мы знаем, что элементы, хранящиеся в типе набора наборов, неупорядочены. Как упорядоченный набор Redis гарантирует порядок? С помощью оценки сопоставление между членами и оценкой сохраняется в упорядоченном наборе, и предоставляется команда обработки оценки, а также порядок получения члена или оценки в соответствии с размером оценки.

Обзор низкоуровневой реализации

Реализация упорядоченных наборов Redis использует структуру данных, называемую таблицей пропуска (называемой таблицей пропуска, с которой можно ознакомиться самостоятельно), а также использует сжатый список, упомянутый выше. При соблюдении определенных условий он преобразуется сам.

 

image.png

 

Детали команды операции заказанного набора

zadd z-key score memer [score member...]Добавить участника с заданной оценкой в ​​отсортированный набор
zrem z-key member [member...]Удаляет заданный элемент из отсортированного набора и возвращает количество удаленных элементов.
zcard z-keyВозвращает количество элементов, содержащихся в отсортированном наборе
zincrby z-key increment memberДобавьте счет участника, чтобы увеличить
zcount z-key min maxВозвращает количество участников со счетом от минимального до максимального.
zrank z-key memberВозвращает ранг элемента-члена в отсортированном наборе
zscore z-key memberВозвращает счет члена-члена
zrange z-key start stop [withscores]Возвращает участников, ранжированных между началом и концом в отсортированном наборе.Если указан необязательный параметр withscores, команда имени также вернет баллы участников.
zrevrank z-key memberВозвращает ранжирование элементов в упорядоченном наборе, а элементы располагаются в порядке убывания оценки.
zrevrange z-key start stopВозвращает элементы упорядоченного набора в пределах заданного диапазона ранжирования, и элементы расположены в порядке убывания оценки.
zrangebyscore z-key min maxВозвращает все элементы отсортированного набора, чьи оценки находятся между минимальным и максимальным значением.

127.0.0.1:6379> zadd zset1 10 a 12 b 1 c 3 d 20 e
(integer) 5
127.0.0.1:6379> zcard zset1
(integer) 5
127.0.0.1:6379> zcount zset1 2 10
(integer) 2
127.0.0.1:6379> zrank zset1 d
(integer) 1
127.0.0.1:6379> zscore zset1 e
"20"
127.0.0.1:6379> zrange zset1 3 5
1) "b"
2) "e"
127.0.0.1:6379> zrevrank zset1 d
(integer) 3
127.0.0.1:6379> zrevrange zset1 3 5
1) "d"
2) "c"
127.0.0.1:6379> zrangebyscore zset1 5 10
1) "a"
127.0.0.1:6379>