Skip to content

Instantly share code, notes, and snippets.

@oleksandr-roskovynskyi
Forked from mantyr/redis
Created September 20, 2020 23:15
Show Gist options
  • Save oleksandr-roskovynskyi/c0e11930ab79cd2dd60be8510e669243 to your computer and use it in GitHub Desktop.
Save oleksandr-roskovynskyi/c0e11930ab79cd2dd60be8510e669243 to your computer and use it in GitHub Desktop.
Redis
Цитата из книги "Маленькая книга о Redis, Карл Сегуин":
Более сложным примером будут команды setbit и getbit. Есть замечательный пост о том, как Spool (Spool - приложение,
на которое ссылаются выше - прим. перев.) использует эти две команды для эффективного ответа на вопрос
«сколько уникальных посетителей было у нас сегодня?».
Для 128 миллионов пользователей ноутбук генерирует ответ менее чем за 50 мс и использует всего лишь 16 МБ памяти.
Книга "Маленькая книга о Redis, Карл Сегуин"
- https://github.com/kondratovich/the-little-redis-book/blob/master/ru/redis-ru.pdf
Небольшой конспект по книги:
Redis
flushdb <db_id> - отчистить базу
select <db_id> - выбрать базу, по умолчанию от 0 до 15
set <ключ> <значение>
get <ключ>
strlen <ключ> – длина значения
getrange <ключ> <начало> <конец> - подстрока значения
append <ключ> <значение> - добавляет текст к концу значения или создаёт новый ключ если его ещё не было
incr <ключ> - инкремент, счётчик, добавляет единицу
incrby <ключ> <сколько добавить> - добавить к инкременту определённое число
setbit
getbit
- http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/
- как Spool (Spool - приложение, на которое ссылаются выше - прим. перев.) использует эти две команды для эффективного ответа на вопрос «сколько уникальных посетителей было у нас сегодня?».
- Для 128 миллионов пользователей ноутбук генерирует ответ менее чем за 50 мс и использует всего лишь 16 МБ памяти.
Хеши (Hashes) - дополнительный уровень адресации данных
hset <ключ> <field> <value> <field> <value> <field> <value> …
hget <ключ> <field>
hgetall <ключ>
1) "<field>"
2) "<value>"
3) "<field>"
4) "<value>"
5) "<field>"
6) "<value>"
hkeys <ключ>
1) "<field>"
2) "<field>"
3) "<field>"
hdel <ключ> <field> <field> <field> <field>
Списки (Lists)
- добавлять значения в список
- получать первое и последнее значение из списка
- манипулировать значениями с заданными индексами
rpush <ключ> <значение> - добавляем значение в конец list
ltrim <ключ> 0 50 - удаляет все значения кроме последних 50ти
- сложность O(N), где N - число значений, которое мы удаляем.
- В этом случае, если мы всегда укорачиваем список после каждой единичной вставки, эта операция имеет постоянную производительность O(1) (потому что N всегда будет равным единице).
Использование ltrim для удаления 1 элемента из списка с миллионом элементов будет быстрее, чем удаление 10 элементов из списка, содержащего сотни элементов.
Множества (Sets)
- множества не упорядоченны
sadd <ключ> <значение> <значение> <значение> <значение> - добавить значения в set
sismember <ключ> <значение> - определить наличие значение, сложность O(1)
sinter <ключ> <ключ> - определить общие значения
sinterstore <ключ> <ключ1> <ключ2> - сохранить результат sinter <ключ1> <ключ2>
Упорядоченные Множества (Sorted Sets)
- упорядочиваем элементы на основании весов
zadd <ключ> <вес> <значение> <вес> <значение> <вес> <значение> <вес> <значение> <вес> <значение>
- O(log(N)), где N - количество элементов, которые уже включены во множество
zcount <ключ> <min> <max> - количество с рейтингом от <min> до <max>
zrevrank <ключ> <значение> - порядковый номер значения, если нет такого значения то результат nil
zremrangebyscore - удаляет элементы упорядоченного множества
- O(log(N)+M), где N - это общее число элементов множества, а M - количество удаляемых элементов
- Другими словами, количество удаляемых элементов, вероятно, сильнее повлияет на производительность, чем общее количество элементов.

sort
- O(N+M*log(M))
- Из этой записи вы можете заключить, что это, вероятно, наиболее сложная в вычислительном плане команда Redis
Хранение ключа для связывания
set users:9001 "{id: 9001, email: [email protected], ...}"
hset users:lookup:email [email protected] 9001
- Мы используем поле как вторичный псевдо-индекс, и получаем ссылку на единственный объект, представляющий пользователя. Чтобы получить пользователя по идентификатору, мы используем обычную команду get:
- get users:9001
- Чтобы получить пользователя по адресу электронной почты, мы воспользуемся сначала hget, а затем get (код на Ruby):
- id = redis.hget('users:lookup:email', '[email protected]')
- user = redis.get("users:#{id}")
getset <ключ> <значение> - устанавливает новое значение и возвращает старое
setnx <ключ> <значение> - проверяет есть ли ключ и если нет – создаёт, иначе ничего не делает
Транзакции
- команды исполняются по порядку
- группа команд выполняется атомарно и в этот момент не происходит никаких других операций над данными
- выполнена либо вся группа команд либо ни одна из них
multi
комманды
exec - выполнить комманды
discard - вместо exec можно отменить команды

multi
hincrby groups:1percent balance -9000000000
hincrby groups:99percent balance 9000000000
exec
Оптимизации
keys bug:1233:* - медленная операция, вместо неё использовать
hset bugs:1233 1 "{id:1, account: 1233, subject: '...'}"
hset bugs:1233 2 "{id:2, account: 1233, subject: '...'}"
hkeys bugs:1233
hdel bugs:1233 2
del bugs:1233
Срок Существования Ключей
expire pages:about 30 - удалит ключ через 30 секунд
expireat pages:about 1356933600 - удалит ключ в 12:00, 31 декабря 2012 года
ttl pages:about - узнать сколько времени будет существовать ключ
persist pages:about - удалить срок существования ключа
setex pages:about 30 '<h1>about us</h1>....'
- срок существования строкового значения 30 секунд, выполняется автомарно
- обновление значения по ключу сотрет информацию о сроке существования, поэтому эту информацию также необходимо обновлять
Публикация Сообщений и Подписка
blpop - возвращает первый элемент и его же удаляет
brpop - возвращает последний элемент и его же удаляет
Подписки на каналы
subscribe channel1 channel2 channel3 ... - подписаться на один или несколько каналов
psubscribe warnings:* - подписаться на каналы по шаблону названия
publish warnings "it's over 9000!" - отправить сообщение в канал
- возвращает количество клиентов получивших сообщение
unsubscribe - отключиться от подписки
punsubscribe - отключиться от подписки
Мониторинг
monitor - показывает список комманд с параметрами которые пришли в redis после включения мониторинга
Журналирование
- Журнал медленных запросов поддерживается в памяти, поэтому его ведение на рабочем сервере даже с низким порогом журналирования не должно создавать проблем.
- По умолчанию в журнале будут храниться последние 1024 записи.
config set slowlog-log-slower-than 0 - включить журналирование всех комманд
config set slowlog-log-slower-than 10 - включить журналирование команд время которых превысило 10 микросекунд
127.0.0.1:6379> slowlog get <количество последних комманд>
1) 1) (integer) 2
2) (integer) 1481803423
3) (integer) 2
4) 1) "get"
2) "test"
2) 1) (integer) 1
2) (integer) 1481803420
3) (integer) 3
4) 1) "set"
2) "test"
3) "ok"
3) 1) (integer) 0
2) (integer) 1481803413
3) (integer) 191
4) 1) "config"
2) "set"
3) "slowlog-log-slower-than"
4) "0"
slowlog len - количество событий в журнале медленных событий
Сортировка
rpush users:leto:guesses 5 9 10 2 4 10 19 2
sort users:leto:guesses
- вернет значения, отсортированные от меньшего к большему
sadd friends:ghanima leto paul chani jessica alia duncan
sort friends:ghanima limit 0 3 desc alpha
- команда выше показывает, сколько значений выводить (с помощью limit)
- получать результат в порядке убывания (посредством desc)
- упорядочивать по алфавиту, а не по числовым значениям (посредством alpha)
Сортировка на основании объектов по ссылкам
sadd watch:leto 12339 1382 338 9338
set severity:12339 3
set severity:1382 2
set severity:338 5
set severity:9338 4
sort watch:leto by severity:* desc
- отсортировать ошибки по критичности от более важных к менее важным
Сортировка на основании полей хеш-таблицы по ссылкам
hset bug:12339 severity 3
hset bug:12339 priority 1
hset bug:12339 details "{id: 12339, ....}"
hset bug:1382 severity 2
hset bug:1382 priority 2
hset bug:1382 details "{id: 1382, ....}"
hset bug:338 severity 5
hset bug:338 priority 3
hset bug:338 details "{id: 338, ....}"
hset bug:9338 severity 4
hset bug:9338 priority 2
hset bug:9338 details "{id: 9338, ....}"
sort watch:leto by bug:*->priority get bug:*->details
- возможность сортировать по параметрам severity (критичность) и priority (приоритет)
- можем указать команде sort, значения каких полей извлекать
127.0.0.1:6379> sort watch:leto by bug:*->priority get bug:*->details get bug:*->priority
1) "{id: 12339, ....}"
2) "1"
3) "{id: 1382, ....}"
4) "2"
5) "{id: 9338, ....}"
6) "2"
7) "{id: 338, ....}"
8) "3"
Сохраняем возвращаемое значение sort в отдельный ключ
sort watch:leto by bug:*->priority get bug:*->details store watch_by_priority:leto
Ограничения
- сотни миллионов
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment