Основы базы данных Redis – как работает интерфейс командной строки Redis, общие команды и примеры проектов
Redis - это популярная база данных в памяти, используемая для различных проектов, таких как кэширование и ограничение скорости.
В этом сообщении в блоге мы увидим, как вы можете использовать Redis в качестве базы данных в памяти, почему вы хотите использовать Redis, и, наконец, мы обсудим несколько важных функций базы данных. Давайте начнем.
Что такое база данных в памяти?
Традиционные базы данных хранят часть базы данных (обычно "горячие" или часто используемые индексы) в памяти для более быстрого доступа, а остальную часть базы данных на диске.
С другой стороны, Redis уделяет большое внимание задержкам и быстрому извлечению и хранению данных. Таким образом, он работает полностью на памяти (RAM) вместо устройств хранения (SSD / HDD). Скорость важна!
Redis - это база данных ключ-значение. Но не позволяйте этому обмануть вас, думая, что это простая база данных. У вас есть много способов хранить и извлекать эти ключи и значения.
Зачем вам нужен Redis?
Вы можете использовать Redis множеством способов. Но есть две основные причины, о которых я могу думать:
- Вы создаете приложение, в котором хотите сделать уровень кода без состояния. Почему? - Потому что, если ваш код не имеет состояния, он масштабируется по горизонтали. Таким образом, вы можете использовать Redis в качестве центральной системы хранения и позволить вашему коду обрабатывать только логику.
- Вы создаете приложение, в котором нескольким приложениям может потребоваться совместное использование данных. Например, что, если кто-то пытается применить грубое насилие к вашему сайту
payments.codedamn.com
, и как только вы это обнаружите, вы также захотите заблокировать ихlogin.codedamn.com
? Redis позволяет нескольким отключенным / слабо подключенным службам совместно использовать общее пространство памяти.
Основы Redis
Redis относительно прост в освоении, поскольку вам нужно знать всего несколько команд. В следующих двух разделах мы рассмотрим несколько основных концепций Redis и некоторые полезные общие команды.
Интерфейс командной строки Redis
У Redis есть интерфейс командной строки, который является версией командной строки REPL. Все, что вы напишете, будет оценено.
На приведенном выше рисунке показано, как выполнить простой PING
или приветственный мир в Redis в одном из упражнений моего курса codedamn Redis (ссылка на курс приведена в конце, если вы хотите его проверить).
Этот Redis REPL очень полезен, когда вы работаете с базой данных в приложении и вам нужно быстро просмотреть несколько ключей или состояние Redis.
Common Redis commands
Trying out common commands on Redis CLI in codedamn course
Here are a few very commonly used commands in Redis to help you learn more about how it works:
SET
SET allows you to set a key to a value in Redis.
Here's an example of how it works:
SET mehul "developer from india"
This sets the key mehul
to the value developer from india
.
GET
GET allows you to get the keys you've set.
Here's the syntax:
GET mehul
This will return the string "developer from india" as we set above.
SETNX
This key will set a value only if the key does not exist. This command has a number of use cases, including not accidentally overwriting the value of a key which might already be present.
Here's how it works:
SET key1 value1
SETNX key1 value2
SETNX key2 value2
После запуска этого примера у вас key1
будет значение value1
и key2
as value2
. Это связано с тем, что вторая команда не будет иметь никакого эффекта, поскольку key1
она уже присутствовала.
MSET
MSET похож на SET, но вы можете установить несколько ключей вместе в одной команде. Вот как это работает:
MSET key1 "value1" key2 "value2" key3 "value3"
Прямо сейчас мы используем key
and value
в качестве префикса для ключей и значений. Но на самом деле, когда вы пишете такой код, легко потерять представление о том, что является ключом, а что значением в такой длинной команде.
Итак, одна вещь, которую вы можете сделать, это всегда заключать свое значение в двойные кавычки и оставлять свои ключи без кавычек (если они являются допустимыми именами ключей без кавычек).
MGET
MGET похож на GET, но он может возвращать несколько значений одновременно, например:
MGET key1 key2 key3 key4
Это вернет четыре значения в виде массива: value1
, value2
, value3
и null
. Мы получили key4
значение null, потому что мы никогда его не устанавливали.
DEL
Эта команда удаляет ключ – достаточно просто, не так ли?
Вот пример:
SET key value
GET key # gives you "value"
DEL key
GET key # null
INCR и DECR
Вы можете использовать эти две команды для увеличения или уменьшения ключа, который является числом. Они очень полезны, и вы будете часто их использовать, потому что Redis может выполнять две операции одновременно – ПОЛУЧИТЬ ключ и УСТАНОВИТЬ ключ в key + 1.
Это позволяет избежать повторных переходов к вашему родительскому приложению и делает операцию также безопасной для выполнения без использования транзакций (подробнее об этом позже)
Вот как они работают:
SET favNum 10
INCR favNum # 11
INCR favNum # 12
DECR favNum # 11
СРОК ДЕЙСТВИЯ ИСТЕКАЕТ
Команда EXPIRE используется для установки таймера истечения срока действия на ключ. Технически это не таймер, а временная метка завершения, после которой ключ всегда будет возвращать значение null, если он не будет установлен снова.
SET bitcoin 100
EXPIRE bitcoin 10
GET bitcoin # 100
# after 10 seconds
GET bitcoin # null
EXPIRE
использует немного больше памяти для хранения этого ключа в целом (потому что теперь вам также нужно хранить, когда срок действия этого ключа истекает). Но вы, вероятно, никогда не будете заботиться об этих накладных расходах.
TTL
С помощью этой команды можно узнать, сколько времени должен жить ключ.
Пример:
SET bitcoin 100
TTL bitcoin # -1
TTL somethingelse # -2
EXPIRE bitcoin 5
# wait 2 seconds
TTL bitcoin # returns 3
# after 1 second
GET bitcoin # null
TTL bitcoin # -2
Итак, чему мы можем научиться из этого кода?
- TTL будет возвращен
-1
, если ключ существует, но срок его действия не истек - TTL вернет
-2
, если ключ не существует - TTL вернет время жизни в секундах, если ключ существует и истекает
SETEX
Вы можете выполнять SET и EXPIRE вместе с SETEX
.
Вот так:
SETEX key 10 value
Здесь ключ - "ключ", значение - "значение", а время жизни (TTL) равно 10. Этот ключ будет сброшен через 10 секунд.
Теперь, когда у вас есть фундаментальные знания об основных командах Redis и о том, как работает интерфейс командной строки, давайте создадим пару проектов и используем эти инструменты в реальной жизни.
Проект 1 – Создание системы кэширования API с помощью Redis
Предварительный просмотр лаборатории построения системы кэширования API на codedamn
Этот проект включает в себя настройку системы кэширования API с помощью Redis, где вы кэшируете результаты с стороннего сервера и используете его в течение некоторого времени.
This is useful so that you are not rate limited by that third party. Also, caching improves your site's speed, so if you implement it correctly it's a win-win for everyone.
You can build this project interactively on codedamn inside the browser using Node.js. If you're interested, you can try the API caching lab for free.
If you're only interested in the solution (and not building it yourself) here's how the core logic will work in Node.js:
app.post('/data', async (req, res) => {
const repo = req.body.repo
const value = await redis.get(repo)
if (value) {
// means we got a cache hit
res.json({
status: 'ok',
stars: value
})
return
}
const response = await fetch(`https://api.github.com/repos/${repo}`).then((t) => t.json())
if (response.stargazers_count != undefined) {
await redis.setex(repo, 60, response.stargazers_count)
}
res.json({
status: 'ok',
stars: response.stargazers_count
})
})
Let's see what's happening here:
- We try to get the
repo
(which is the passed repo format -facebook/react
) from our Redis cache. If present, great! We return the star count from our redis cache, saving us a roundtrip to GitHub's servers. - Если мы не находим его в кэше, мы делаем запрос к серверам GitHub и получаем количество звезд. Мы проверяем, не определено ли количество звездочек (в случае, если репозиторий не существует / является частным). Если у него есть значение, мы
setex
вводим значение с таймаутом 60 секунд. - Мы устанавливаем тайм-аут, потому что не хотим со временем обслуживать устаревшие значения. Это помогает нам обновлять количество звездочек не реже одного раза в минуту.
Вот полный исходный код:
codedamn-классы / redis-nodejs-classroom
Проект 2 - API с ограничением скорости с Redis
Предварительный просмотр API ограничения скорости с Redis
Этот проект включает ограничение скорости для определенной конечной точки, чтобы защитить ее от злоумышленников, а затем заблокировать им доступ к этому конкретному API.
Это очень полезно для входа в систему и чувствительных конечных точек API, где вы не хотите, чтобы один человек обращался к вашей конечной точке с тысячами запросов.
В этой лаборатории мы выполняем ограничение скорости по IP-адресу. Если вы хотите попробовать эту кодовую лабораторию, вы можете попробовать ее бесплатно на codedamn.
Если вас интересует только решение (а не создание его самостоятельно), вот как основная логика будет работать в Node.js:
app.post('/api/route', async (req, res) => {
// add data here
const ip = req.headers['x-forwarded-for'] || req.ip
const reqs = await redis.incr(ip)
await redis.expire(ip, 2)
if (reqs > 15) {
return res.json({
status: 'rate-limited'
})
} else if (reqs > 10) {
return res.json({
status: 'about-to-rate-limit'
})
} else {
res.json({
status: 'ok'
})
}
})
Давайте разберемся с этим блоком кода:
- Мы пытаемся извлечь IP-адрес из
x-forwarded-for
заголовка (или вы можете использоватьreq.ip
, как мы используем express) - Мы
INCR
вводим поле IP-адреса. Если бы наш ключ в Redis никогда не существовал, INCR автоматически установил бы его в 0 и увеличил, то есть окончательно установил бы его в 1. - Мы устанавливаем срок действия ключа через 2 секунды. В идеале вам нужно большее значение - но это то, что указано выше в задаче codedamn, так что у нас это есть.
- Наконец, мы проверяем количество запросов, если они превышают определенный порог, мы блокируем доступ запроса к основному телу функции.
Вот полное решение:
codedamn-классы / redis-nodejs-classroom
Подробнее о Redis
Redis - это гораздо больше, чем то, что мы узнали до сих пор. Но хорошо то, что мы узнали достаточно, чтобы уже начать работать с ним!
В этом разделе давайте рассмотрим еще несколько основ Redis.
Redis является однопоточным
Redis выполняется как однопоточный процесс даже в многоядерной системе, поддерживающей многопоточность. Это не кошмар производительности, а мера безопасности против непоследовательного чтения / записи в многопоточной среде.
Если бы Redis был многопоточным, чтобы обеспечить потокобезопасность при доступе к одному ключу, вы бы в конечном итоге решили использовать какой-то механизм блокировки, который, вероятно, в любом случае работал бы хуже, чем однопоточный / последовательный доступ.
Транзакции Redis
Конечно, вы не можете сделать все в Redis одной командой. Но вы, конечно, можете попросить его выполнить блок команд за один раз (то есть никто другой не разговаривает с Redis, пока он выполняет этот блок). Вы можете сделать это с помощью MULTI
команды.
Вот как это работает:
MULTI
SET hello world
SET yo lo
SET number 1
INCR number
EXPIRE hello 10
EXPIRE yo 5
EXEC
Это выполнит все эти операции за один раз, то есть после этого он вообще ничего не MULTI
будет запускать и запустит все сразу, как только увидит EXEC
ключевое слово.
Redis включает поддержку списков и наборов для более сложных вариантов использования. Вы также можете использовать Redis в качестве службы вещания, в которой вы публикуете на канале, а другие пользователи, подписавшиеся на канал, получают уведомление. Это очень полезно в архитектуре с несколькими клиентами.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.