redis: Introduction

redis.io
redis commands
Маленькая книга о Redis
Redis in Action
Redis 4.x Cookbook

Introduction

Запускаем redis в контейнере

Самый примитивный запуск redis в контейнере осуществляется командой
docker container run -h redisSrv --name redisServer -d redis

При необходимости кастомизации конфигурационного файла redis.conf, контейнер с redis необходимо запускать так:

docker container run \
-h redisSrv \
--name redisSrv \
-d \
-v /myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis \
redis-server /usr/local/etc/redis/redis.conf

где оригинал redis.conf можно скачать отсюда (в ссылке необходимо поменять версию redis, если он у вас отличается от моего 4.0.11)
Помимо всего прочего если планируется использовать постоянное хранилище(Redis Persistence), то нужно примантировать том с хостовой тачки в контейнер.
Создаём том:

docker volume create redisSrv_vol

Запускамем redis в контейнере

docker container run \
-h redisSrv \
--name redisSrv \
-d \
-v redisSrv_vol:/data \
-v /myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis \
redis-server /usr/local/etc/redis/redis.conf

Т.к. в моём примере не запланирован доступ к redis из вне, то я не делаю пробросов портов на хостовую тачку.
В ином случае можно добавить команду
-p 6379:6379
при запуске redis.

Подключение к redis

Подключиться к redis можно с помощью утилиты redis-cli несколькими способами:
1. Можно установить пакет redis-tools для вашей ОС. redis-cli входит в данный пакет, по крайней мере для Ubunta точно.
2. Скачать архив с официального сайта, разархивировать файл и в папке bin/ найт redis-cli.
3. Способ которым буду пользоваться я — это подключаться с redis с помощью redis-cli в самом контейнере

docker container exec -it redisSrv redis-cli
127.0.0.1:6379>

В качестве знакомства с redis введем первую команду info
Данная команда вернёт информацию и статистику о сервере.

127.0.0.1:6379> info
# Server
redis_version:4.0.11
redis_git_sha1:00000000
....
# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
....
# Memory
used_memory:849440
used_memory_human:829.53K
used_memory_rss:4091904
....
# Persistence
loading:0
rdb_changes_since_last_save:0
aof_enabled:0
aof_rewrite_in_progress:0
....
# Stats
total_connections_received:1
total_commands_processed:1
instantaneous_ops_per_sec:0
....
# Replication
role:master
connected_slaves:0
....
# CPU
used_cpu_sys:2.47
used_cpu_user:1.04
....
# Cluster
cluster_enabled:0
....
# Keyspace

где
Server — базовая информация о Redis сервере.
Clients — статус и метрики клиентских подключений.
Memory — общие показатели потребления памяти.
Persistence — состояние и показатели, связанные с сохранением данных.
Stats — общая статистика.
Replication -состояние и показатели репликации master-slave.
CPU — потребление CPU.
Cluster — статус redis кластера.
Keyspace — статисика баз данных.

Можно вывести отдельную секцию данных

127.0.0.1:6379> info stats
# Stats
total_connections_received:1
total_commands_processed:4
instantaneous_ops_per_sec:0
....

Конфигурация redis

Если при старте сервиса указывать еще какие-либо опции, то они будут «перебивать» параметры указанные в конфигурационном файле.

redis-server /usr/local/etc/redis/redis.conf --port 7777

Сервер запустится на 7777 порту вместо 6379.

CONFIG SET/GET/REWRITE

Для конфигурации сервера из командой строки используются команды
CONFIG SET
CONFIG GET
CONFIG REWRITE

Получаем текущую конфигурацию опции appendonly
CONFIG GET appendonly
1) "appendonly"
2) "no"

Проверяем данную конфигурации в файле
grep appendonly redis.conf
appendonly no

Меняем данный параметр
CONFIG SET appendonly yes
OK

Проверяем, что параметр сменил своё значение
CONFIG GET appendonly
1) "appendonly"
2) "yes"

Сохраняем
CONFIG REWRITE
OK

Смотрим файл
grep appendonly redis.conf
appendonly yes

Persistence

У redis есть механизмы позволяющие сохранять данные из оперативной памяти на жёсткий диск — RDB и AOF.
RDB — мгновенный снимок данных, подходящий для бэкапов и восстановления.
AOF — журнал операций записи, который воспроизводится при запуске сервера.

RDB

Для вкючения RDB в конфигурацию redis.conf необходимо добавить опцию save seconds changes
где changes минимальное кол-во изменений в БД за seconds секунд
т.е. save 60 10000 — означает сделать дамп БД, если произошло не меньше 10000 изменений в БД за 60 секунд

Получить текущую конфигурацию RDB можно так:

grep ^save redis.conf
save 900 1
save 300 10
save 60 10000

или так

CONFIG GET SAVE
1) "save"
2) "900 1 300 10 60 10000"

Для нашего контейнера, RDB файл будет писаться в папку /data файл dump.rdb. Это как раз тот самый том redisSrv_vol, который создавали перед запуском контейнера.

Чтобы сделать RDB снэпшот вручную нужно воспользоваться командами SAVE или BGSAVE
SAVE в проде не рекомендуется для использования потому что он блокирует остальных клиентов на время дампа.

Имя файла задаётся опцией dbfilename

CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"

Имя папки, куда пишется RDB файл задаётся опцией dir

CONFIG GET dir
1) "dir"
2) "/data"

AOF

AOF — append-only log — запись команд в лог файл. Как только redis получает команду записи в результате которой будут изменены данные в памяти, то данная команда пишется в aof лог файл.
Но если рассмотреть процесс записи в файл, то предварительно данные сперва попадают в буфер и только затем уже пишутся на диск в файл. Данный процесс выполняется системным вызовом fsync().
С помощью опции appendfsync можно кастомизировать процесс записи в aof файл, она может иметь три возможных варианта:
1. always:fsync() — вызывается redis для записи абсолютно всех команд. В случае возникновения проблем данная опция гарантирует потерю только одно последней команды. Но данная опция несёт большую нагрузку на диск, что сказывается на производительности сервера.
2. everysec:fsync() — вызывается redis раз в секунду. При такой настройки потери данных могут быть только за последнюю секунду при возникновении проблем с redis. Данная опция рекомендуется, как самая сбалансированная между производительностью и отказоустойчивостью.
3. no:fsync() — redis не принимает участия в решении о записи на диск, процесс записи из буфера на дсик контролируется ОС, в большинстве Linux систем запись происходит каждые 30 сек.

Имя фала для aof лога задаётся опцией appendfilename, по дефолту имя «appendonly.aof» в нашем случае так же пишется в /dataa папку.

Получить текущую конфигурацию AOF можно так:

grep "^appendonly" redis.conf
appendonly yes

или так

CONFIG GET appendonly
1) "appendonly"
2) "yes"

При запуске redis перечитывает данный файл и выполнят команды последовательно.
Для того чтоб данный лог файл не разрастался его необходимо периодически чистить, делается это командой BGREWRITEAOF. Данная команда удаляет все старые значения ключей и оставляет только последнии, самые актуальные.
Для автоматизации процесса чистки aof файла используются опции:
auto-aof-rewrite-percentage — запоминает размер последней чистки файла и если объём файла становится больше указанного %,то запускается новая чистка.
auto-aof-rewrite-min-size — запустить чистку файла, если его размер больше чем указано в данной опции(по умолчанию 64 MB)
Если в случае падения redis aof файл повреждается, то для его восстановления используют команду
redis-check-aof --fix appendonly.aof

Комбинация RDB и AOF

В сравнении с AOF, RDB занимает меньше места и процесс восстановления проходит быстрее. Но данные между двумя RDB снэпшотами могут оказаться потерянными.
Для того чтоб минимизировать потери и использовать лучшее из обоих подходов в 4.x версии redis добавили опцию для их совместного использования — aof-use-rdb-preamble.
Т.е. сперва включаются RDB и AOF, как описывалось выше, а затем
CONFIG SET aof-use-rdb-preamble yes
Когда данная опция включена то во время реврайта (BGREWRITEAOF) redis выгружает данные из памяти в RDB формате в качестве приамбулы для AOF файла. После этого redis продолжает писать AOF файл в стандартом формате. Данная возможность позволяет redis писать и загружать файл более быстрее в силу использования RDB формата.

Security

Сам по себе redis имеет бедный набор инструментов для обеспечения безопасности, поэтому необходимо задействовать набор стандартных практик без-ти ОС.
1. Не вывешивать redis в публичную сеть, а оставлять только в локальной сети.
За данную настройку отвечает опция bind. Так же можно сменить стандартный порт redis — опция port.
В redis имеется опция protected-mode (включена по умолчанию), в случае если redis сконфигурирован слушать все интерфейсы сервера (не сконфигурирована опция bind) и не включена аутентификация, то redis не обрабатывает запросы кроме тех что приходят на 127.0.0.1 или Unix сокет.
2. Ограничить доступ к redis файрволом ОС (стандартный порт redis 6379), т.е. дать доступ к серверу только с доверенных хостов локальной сети.
3. Включить аутентификацию в redis — опция requirepass.
4. Запускать redis из под непривилегированного пользователя, без прав подключения по ssh.
5. Т.к. пароль хранится в конфиге в открытом виде, то ограничить возможность чтения файла redis.conf. И передаётся пароль тоже в открытом виде, поэтому желательно чтоб сервер и клиенты оказывались в одном сегменте сети, чтоб минимизировать возможность прослушки трафика.
6. Замена или отключение критичных команд, таких как — CONFIG, FLUSHALL,FLUSHDB
В redis.conf добавить строки

rename-command FLUSHALL Ot6Eiy3Phoong0Ei6Yea4LahY4lu1Phee0ahkeCh2oogheitab
rename-command FLUSHDB or2azeDoaraigi9aeph6zor2boNgei8Ahcheeteiv0ahy3gaif
rename-command CONFIG eib4Eiwie8quae4ci6vu2Chuo5eif9uediT4quaiwuuqu9Sane

для полного отключения команды
rename-command CONFIG ""

Data types

В redis имеются следующие типы данных
strings — общий и самый используемый тип данных в программировании и приложениях. Так же является фундаментальным типом в redis в котором все ключи являются строками.
list — упорядоченный список строк,очень полезный тип данных. Список хранит последовательность объектов и может быть использован, как очередь или стэк.
hashes — представляет собой тип данных воссоздающих отношения поле-значение, аналог dict в python или struct в golang.
sets — мн-во уникальных и не упорядоченных объектов
sorted sets — мн-во уникальных и упорядоченных объектов,сортиурет от меньшего к большему

STRINGS

Redis string commands
set KEY VALUE — выставить значение ключа (если ключ уже существует, то перезаписывает его)
get KEY — получить значение ключа

127.0.0.1:6379> set mykey1 val1
OK
127.0.0.1:6379> set mykey2 12345
OK
127.0.0.1:6379> set mykey3 "blabla bla bla blablablablablabla"
OK

127.0.0.1:6379> get mykey1
"val1"
127.0.0.1:6379> get mykey2
"12345"
127.0.0.1:6379> get mykey3
"blabla bla bla blablablablablabla"

append KEY VALUE — добавляет значение в конец строки. Если ключа не существует, то создается пустой ключ и затем добавляется значение.

APPEND mykey1 qwerty
(integer) 10
127.0.0.1:6379> get mykey1
"val1qwerty"

setrange KEY OFFSET VALUE — перезапись части строки
getrange KEY OFFSET — получить часть значения

127.0.0.1:6379> SETRANGE mykey3  6 " QWERTYqwerty qwertyQwerty qwerty"
(integer) 39
127.0.0.1:6379> get mykey3
"blabla QWERTYqwerty qwertyQwerty qwerty"


127.0.0.1:6379> getrange mykey3 6 -1
" QWERTYqwerty qwertyQwerty qwerty"
127.0.0.1:6379> getrange mykey3 6 8
" QW"
127.0.0.1:6379> getrange mykey3 0 -1
"blabla QWERTYqwerty qwertyQwerty qwerty"

setnx KEY VALUE — сначала проверяет, существует ли ключ, и устанавливает значение только в том случае, если ключ не существовал
setex KEY SECONDS VALUE — добавить ключ и его время жизни — через которые ключ удалится автоматически

127.0.0.1:6379> get mykey2
"12345"
127.0.0.1:6379> setnx mykey2 100
(integer) 0
127.0.0.1:6379> get mykey2
"12345"
127.0.0.1:6379> setnx mykey4 100
(integer) 1
127.0.0.1:6379> get mykey4
"100"

127.0.0.1:6379> setex mykey5 5 1000
OK
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
"1000"
127.0.0.1:6379> get mykey5
(nil)

mset KEY VALUE KEY VALUE KEY VALUE KEY VALUE etc ... — добавить сразу несколько ключей
mget KEY KEY KEY etc... — получить сразу несколько значений ключей

127.0.0.1:6379> mset k1 v1 k2 10 k3 "test test TETSTETSTETST" k4 3.14
OK
127.0.0.1:6379> mget k1 k2 k3 k4
1) "v1"
2) "10"
3) "test test TETSTETSTETST"
4) "3.14"

strlen KEY — вернуть длину значения ключа

127.0.0.1:6379> STRLEN mykey3
(integer) 39
127.0.0.1:6379> get mykey3
"blabla QWERTYqwerty qwertyQwerty qwerty"

incr KEY — инкремент значения на 1
incrby KEY VALUE — инкремент значения на VALUE
decr KEY — декремент значения на 1
decrby KEY VALUE — декремент значения на VALUE

127.0.0.1:6379> get mykey4
"100"
127.0.0.1:6379> incr mykey4
(integer) 101
127.0.0.1:6379> incrby mykey4 49
(integer) 150
127.0.0.1:6379> get mykey4
"150"

127.0.0.1:6379> decr mykey4
(integer) 149
127.0.0.1:6379> get mykey4
"149"
127.0.0.1:6379> decrby mykey4 49
(integer) 100
127.0.0.1:6379> get mykey4
"100"

getset KEY VALUE — вернуть старое значение ключа и выставить новое

127.0.0.1:6379> get mykey3
"blabla QWERTYqwerty qwertyQwerty qwerty"
127.0.0.1:6379> getset mykey3 "NEWBLABLABLABLA"
"blabla QWERTYqwerty qwertyQwerty qwerty"
127.0.0.1:6379> get mykey3
"NEWBLABLABLABLA"

Redis использует три кодировки для хранения строковых переменных и в зависимости от их значений решает какую кодировку использовать.
int — для строк представляющих 64 битное знаковое целое
embstr — для строк менее или равное 44 байтам.
raw — для строк длиной более 44 байт
object encoding KEY — команда позволяющая узнать, какая кодировка используется

127.0.0.1:6379> set mykey1 val1
OK
127.0.0.1:6379> set mykey2 12345
OK
127.0.0.1:6379> set mykey3 "blabla bla bla blablablablablabla blabla bla bla blablablablablabla blabla bla bla blablablablablabla"
OK

127.0.0.1:6379> object encoding mykey1
"embstr"
127.0.0.1:6379> object encoding mykey2
"int"
127.0.0.1:6379> object encoding mykey3
"raw"

LIST

Redis list commands
rpush KEY ITEM1 ITEM2 etc... — добавить эл-нты «с правого конца» списка, если список не существует, то он создается.
lpush KEY ITEM1 ITEM2 etc... — добавить эл-нты «с левого конца» списка, если список не существует, то он создается.
linsert KEY BEFORE|AFTER PIVOT ITEM1 ITEM2 etc... — добавить эл-нты перед или после указанного эл-нта
lpushx/ rpushx — добавлять эл-ты соответственно с «левой или правой стороны» только если список уже существеут

127.0.0.1:6379> rpush templist1 item1 1234 "blablabla qwerty blablabla qwerty blablabla qwerty"
(integer) 3
127.0.0.1:6379> lrange templist1 0 -1
1) "item1"
2) "1234"
3) "blablabla qwerty blablabla qwerty blablabla qwerty"

127.0.0.1:6379> lpush templist1 1 2 3
(integer) 6
127.0.0.1:6379> lrange templist1 0 -1
1) "3"
2) "2"
3) "1"
4) "item1"
5) "1234"
6) "blablabla qwerty blablabla qwerty blablabla qwerty"

insert templist1 before 1234 666
(integer) 7
127.0.0.1:6379> LRANGE templist1 0 -1
1) "3"
2) "2"
3) "1"
4) "item1"
5) "666"
6) "1234"
7) "blablabla qwerty blablabla qwerty blablabla qwerty"

lindex KEY INDEX — вернуть значение эл-та по указанному индексу
lset KEY INDEX ITEM — установиьт значение эл-та в списке по указанному индексу

127.0.0.1:6379> lindex templist1 0
"3"
127.0.0.1:6379> lindex templist1 2
"1"
127.0.0.1:6379> lindex templist1 7
"1234"
127.0.0.1:6379> lindex templist1 6
"666"

127.0.0.1:6379> lindex templist1 6
"666"
127.0.0.1:6379> lset templist1 6 111
OK
127.0.0.1:6379> lindex templist1 6
"111"

lrange KEY 0 -1 — вернуть значения всего списка

127.0.0.1:6379> lrange templist1 0 -1
1) "3"
2) "2"
3) "1"
4) "item1"
5) "111"
6) "666"
7) "111"
8) "1234"
9) "blablabla qwerty blablabla qwerty blablabla qwerty"

lpop KEY — удалить эл-нт «с левого конца» списка
rpop KEY — удалить эл-нт «с правого конца» списка
ltrim NAME 0 ITEMNUM — укоротить список, сохраняется только указанный диапазон

127.0.0.1:6379> lpop templist1
"3"
127.0.0.1:6379> rpop templist1
"blablabla qwerty blablabla qwerty blablabla qwerty"
127.0.0.1:6379> lrange templist1 0 -1
1) "2"
2) "1"
3) "item1"
4) "111"
5) "666"
6) "111"
7) "1234"

127.0.0.1:6379> lrange templist1 0 -1
1) "2"
2) "1"
3) "item1"
4) "111"
5) "666"
6) "111"
7) "1234"
127.0.0.1:6379> ltrim templist1 3 5
OK
127.0.0.1:6379> lrange templist1 0 -1
1) "111"
2) "666"
3) "111"

HASHES

Redis hash commands

hset KEY FILED VALUE — установить значение поля
hget KEY FIELD — получить значение поля

hset user:1 firstName Bob
(integer) 1
hget user:1 firstName
"Bob"

hmset KEY FILED1 VALUE1 FILED2 VALUE2 etc... — установить несколько значений для нескольких полей сразу
hmget KEY FILED1 FILED2 etc... — получить несколько значений полей сразу

127.0.0.1:6379> hmset user:1 lastName Hawk age 25 dep "Developers" phone "111222333444"
OK
127.0.0.1:6379> hmget user:1 firstName lastName age dep phone
1) "Bob"
2) "Hawk"
3) "25"
4) "Developers"
5) "111222333444"

hgetall KEY — получить все поля и значения
hkeys KEY — получить имена всех полей
hdel KEY FILED — удалить одно поле

127.0.0.1:6379> hgetall user:1
 1) "firstName"
 2) "Bob"
 3) "lastName"
 4) "Hawk"
 5) "age"
 6) "25"
 7) "dep"
 8) "Developers"
 9) "phone"
10) "111222333444"

127.0.0.1:6379> hkeys user:1
1) "firstName"
2) "lastName"
3) "age"
4) "dep"
5) "phone"

127.0.0.1:6379> HDEL user:1 phone age
(integer) 2
127.0.0.1:6379> hgetall user:1
1) "firstName"
2) "Bob"
3) "lastName"
4) "Hawk"
5) "dep"
6) "Developers"

hexists KEY FILED — проверка существования поля

127.0.0.1:6379> hexists user:1 phone 
(integer) 0
127.0.0.1:6379> hexists user:1 firstName
(integer) 1

SETS

Redis set commands

sadd KEY ITEM1 ITEM2 ITEM3 etc... — создать мн-во

127.0.0.1:6379> sadd tempkey 1234 1234 test "balblabla blablabla blabla bla"
(integer) 3

sismember KEY ITEM — проверка принадлежности указанного эл-та указанному мн-ву

127.0.0.1:6379> sismember tempkey 1234
(integer) 1
127.0.0.1:6379> sismember tempkey 12345
(integer) 0

smembers KEY — показать всё мн-во

127.0.0.1:6379> smembers tempkey
1) "1234"
2) "balblabla blablabla blabla bla"
3) "test"

scard KEY — показать кол-во эл-ов в мн-ве

127.0.0.1:6379> scard tempkey
(integer) 3

srem KEY ITEM1 ITEM2 ITEM3 etc… — удалить эл-ты из мн-ва

(integer) 3
127.0.0.1:6379> srem tempkey "balblabla blablabla blabla bla" "test"
(integer) 2
127.0.0.1:6379> smembers tempkey
1) "1234"

SORTED SET

Redis sorted set commands

zadd KEY SCORE1 ITEM1 SCORE2 ITEM2 SCORE3 ITEM3 etc... — создать мн-во

127.0.0.1:6379> zadd cars 100 toyota 80 nisan 70 mazda 60 subaru 50 suzuki
(integer) 5

zrange KEY 0 -1 — показать всё мно-во

127.0.0.1:6379> zrange cars 0 -1
1) "suzuki"
2) "subaru"
3) "mazda"
4) "nisan"
5) "toyota"

zrange KEY 0 -1 withscores — показать всё мн-во с весами значений

127.0.0.1:6379> zrange cars 0 -1 withscores
 1) "suzuki"
 2) "50"
 3) "subaru"
 4) "60"
 5) "mazda"
 6) "70"
 7) "nisan"
 8) "80"
 9) "toyota"
10) "100"

zrevrange KEY 0 -1 withscores — показать всё мн-во сортированного в обратном порядке с весами значений

127.0.0.1:6379> zrevrange cars 0 -1 withscores
 1) "toyota"
 2) "100"
 3) "nisan"
 4) "80"
 5) "mazda"
 6) "70"
 7) "subaru"
 8) "60"
 9) "suzuki"
10) "50"

zcount KEY SCORE1 SCORE2 etc... — показать кол-во объектов с рейтингами между score1 и score2

127.0.0.1:6379> zcount cars 60 80
(integer) 3

zrank KEY ITEM — показать индекс эл-та в мн-ве

127.0.0.1:6379> zrank cars nisan
(integer) 3

zrevrank KEY ITEM — показать индекс эл-та в мн-ве сортированного в обратном порядке

127.0.0.1:6379> zrevrank cars nisan
(integer) 1

zincrby KEY INCREMENT ITEM — увеличить вес эл-та на указанное число

127.0.0.1:6379> zincrby cars 10 toyota
"110"

zscore — показать вес эл-та

127.0.0.1:6379> zscore cars toyota
"110"

Managing keys

в redis нет привычных имён баз данных. Базы обозначаются цифрами 0,1,2 — 15
select NUM — перключение между БД
flushdb — удалить все данные в БД
flushall — удаление всех данных из всех БД
dbsize — показать какое кол-вл ключей существует в БД
type KEY — показать тип ключа
rename KEY NEWEKEY — переименовать ключ
key * или scan 0 — показать все ключи
exists KEY — проверка существования ключа (если да, то вернёт 1, если нет,то 0)
del KEY или unlink KEY — удалить ключ

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *