В прошлом уроке мы учились управлять ключами. Под ключом всегда лежит значение какого-то типа, и самый простой и самый частый тип это строка. В строке хранят кэш страниц, JSON с карточкой товара, токены, флаги и счётчики. Сегодня разбираем, что умеет SET кроме простой записи и как работать со строками по кусочкам.
Ячейка, в которую влезет что угодно
Вернёмся к камере хранения. В ячейку можно положить что угодно: письмо, коробку, фотографию. Камере всё равно, что внутри, она хранит предмет целиком и отдаёт его целиком.
Строка в Redis такая же ячейка. Строка это последовательность байтов до 512 МБ. Redis не заглядывает внутрь: там может быть текст, JSON, число или даже картинка. Такие строки называют бинарно безопасными: какие байты положил, такие и получишь.
SET и GET
Простую запись и чтение мы уже видели:
127.0.0.1:6379> SET book:1:title "Master and Margarita"
OK
127.0.0.1:6379> GET book:1:title
"Master and Margarita"
Значение с пробелами берут в кавычки, иначе redis-cli примет слова за отдельные аргументы. Если ключ уже был, SET перезапишет его без вопросов. Иногда так и нужно, а иногда это ошибка, и тогда помогают флаги.
NX: только если ключа нет
NX значит «записать, только если ключа ещё нет»:
127.0.0.1:6379> SET book:1:title "Heart of a Dog" NX
(nil)
127.0.0.1:6379> GET book:1:title
"Master and Margarita"
127.0.0.1:6379> SET book:2:title "Roadside Picnic" NX
OK
Ключ book:1:title уже был, поэтому запись не прошла: ответ (nil) вместо OK. Для book:2:title всё получилось.
С NX и сроком жизни строится простейшая блокировка: «кто первый поставил ключ, тот и работает»:
127.0.0.1:6379> SET lock:order:7 worker-1 NX EX 30
OK
127.0.0.1:6379> SET lock:order:7 worker-2 NX EX 30
(nil)
Первый обработчик занял заказ на 30 секунд, второй получил отказ. Срок нужен на случай, если первый упадёт и не освободит блокировку. Здесь много тонкостей, распределённым блокировкам посвящён отдельный урок раздела.
XX: только если ключ есть
XX работает наоборот: обновить, только если ключ уже существует.
127.0.0.1:6379> SET book:3:title "Overcoat" XX
(nil)
127.0.0.1:6379> GET book:3:title
(nil)
Ключа book:3:title не было, и XX его не создал. Так обновляют данные, не плодя случайных ключей с опечатками.
GET: записать и получить старое
Флаг GET возвращает прежнее значение и тут же записывает новое, одной командой:
127.0.0.1:6379> SET book:1:title "The Master and Margarita" GET
"Master and Margarita"
127.0.0.1:6379> GET book:1:title
"The Master and Margarita"
Две отдельные команды GET и SET здесь хуже: между ними другой клиент может успеть поменять значение. Одна команда в Redis выполняется целиком, никто не вклинится. Похожая команда GETDEL читает значение и удаляет ключ.
Все флаги сочетаются: SET key value NX EX 30 уже встречался выше.
урок из курса
Урок из курса «Redis с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.