Redis для приложений на Python
База данных Redis появилась в 2009 году, но ей все еще предстоит пройти проверку временем и полезностью в реальном мире, хотя многие разработчики и признают, что уже активно используют ее в повседневной практике.
Почему Redis?
Обычно при упоминании Redis у многих возникают ассоциации с базами данных NoSQL, но это в корне неверно. У Redis нет с ними ничего общего: ни в плане своего позиционирования, ни в плане исполнения. MongoDB, например, хранит данные на диске.
Выделение места для записей подразумевает, что эти данные должны быть сохранены: аккаунты пользователей, записи в блог, разрешения и так далее. Большая часть данных любых приложений относится к этой категории.
Тем не менее есть и исключения. Было бы крайне неэффективно хранить, например, содержимое корзины пользователя или информацию о последней посещенной странице. В краткосрочной перспективе такая информация была бы полезной, но нагружать ею базы данных, основанные на транзакционных системах — не очень разумно. Благо, существует такое понятие как RAM (ОЗУ или оперативное запоминающее устройство).
Redis — это резидентная база данных (такая, которая хранит записи прямо в оперативной памяти) в виде пар ключ-значение. Чтение и запись в память происходит намного быстрее, чем в случае с дисками, поэтому такой подход отлично подходит для хранения второстепенных данных.
Это улучшает пользовательский опыт, но одновременно делает базы данных чистыми. Если же в будущем решается, что такие данные тоже нужно хранить, то их всегда можно записать на диск (например, в базу данных SQL).
В этом руководстве познакомимся с библиотекой Python для Redis под названием redis-py. В среде Python его называют просто redis. Официальная документация этой библиотеки — просто одна страница с перечислением всех методов в алфавитном порядке.
Если вы планируете использовать Redis с каким-либо из фреймворков, то рекомендуется выбирать конкретную библиотеку: например, Flask-Redis, а не redis-py. Однако все они преимущественно повторяют синтаксис redis-py и имеют несколько минимальных отличий.
Установка Redis
Что бы протестировать работу Redis рекомендую использовать облачное решение. Зарегистрируйтесь на Redis Labs, они дают бесплатный сервер для обучения и тестирования.
4. Создайте базу данных:
После активации приложения вам понадобятся хост(Endpoint) и пароль (Default User Password).
Далее установим redis:
Строка подключения к Redis
Как и в случае с обычными базами данных подключить экземпляр Redis можно с помощью строки подключения. Вот как такая выглядит в Redis:
Разберем по пунктам:
Создание клиента Redis
URI есть. Теперь нужно подключиться к Redis, создав объект клиента:
Пример использования Redis
Хранилище ключ-значение Redis очень напоминает словари Python, отсюда и расшифровка — Remote Dictionary Service (удаленный сервис словарей). Ключи — это всегда строки, но значениями могут быть разные типы данных. Заполним приложение Redis несколькими записями, чтобы лучше понять, как они работают:
r.set([KEY], [VALUE]) — это основной синтаксис, чтобы задавать одиночные значения. Первый параметр — это ключ, а второй — присваиваемое ему значение.
По аналогии с обычными базами данных подключение к Redis осуществляется с помощью графического интерфейса, по типу TablePlus для проверки данных. Вот как выглядит тестовая база после выполнения кода выше:
| KEY | VALUE | TYPE | TTL |
|---|---|---|---|
| user_agent | Mozilla/5.0 (Macintosh; Intel Mac OS X 11) | STRING | -1 |
| last_page_visited | home | STRING | -1 |
| ip_address | 127.0.0.0 | STRING | -1 |
| timestamp | 1610803181 | STRING | -1 |
Кажется, операция прошла успешно. Узнать кое-что о Redis можно, просто взглянув на таблицу. Начнем с колонки type.
Типы данных в Redis
В Redis могут храниться данные 5 типов:
Срок хранения данных
Вернемся к примеру, где хранится информация о сессии пользователя и зададим срок действия данных:
Что такое redis python
Установка
Чтобы установить redis-py выполните:
или воспользуйтесь pip
Проверка
Описание API
В официальной документации по Redis < target="_blank" >вы найдете подробное описание команд. Redis-py предоставляет два клиентских класса для работы с этими командами. Класс StrictRedis максимально приближен к официальному синтаксису команд самого Redis, за некоторым исключением:
Так же класс Redis будучи наследником StrictRedis использует некоторые команды для обеспечения поддержки старых версий redis-py:
Пул соединений
За кулисами redis-py использует пул соединений для управления соединениями с сервером Redis. По-умолчанию, каждый экземпляр Redis создает свой собственный пул соединений. Такого поведения можно избежать, передав экземпляр уже существующего пула Redis классу как аргумент connection_pool. Такое решение может потребоваться при реализации сегментирования на клиентской стороне или получения полного контроля над соединениями.
Соединения
Парсеры
Callback функции ответа
Многопоточность
Экземпляры клиентов Redis можно использовать в нескольких потоках одновременно. Соединения извлекаются из пула только при выполнении команд, и возвращаются после их завершения. Выполнение команды никогда не изменяет состояние экземпляра клиентского класса.
Поэтому redis-py не поддерживает команду SELECT на стороне клиента. При использовании нескольких БД в пределах одного приложения, следует создавать отдельные экземпляры клиентов, а по возможности и отдельные пулы соединений, для каждой базы данных. Не рекомендуется передавать PubSub или Pipline объекты между потоками.
Pipelines
Piplines довольны просты в применении:
Для упрощения, каждая команда после буферизации возвращает объект pipeline. То есть можно выполнять команды по цепочке:
Так же pipeline автоматически выполняет команды группами. Чтобы изменить такое поведение, достаточно отключить транзакции:
Метод transaction упрощает отслеживание ошибок. Он принимает исполняемую функцию в качестве параметра, объект типа pipeline и любой набор ключей для отслеживания. Таким образом мы можем переписать наше решение следующим образом:
Публикация/Подписка
После создания объекта можно подписываться на каналы:
Теперь PubSub подписан на указанные каналы. Подтверждение этому являются поступающие сообщения:
Каждое сообщение представляет собой словарь со следующими ключами:
Давайте отправим сообщение.
Отписаться также просто. Если не передавать аргументов команде, то мы отпишемся от всех каналов.
При поступлении сообщения через канал или паттерн, такой словарь создается и передается обработчику сообщения. В нашем случае, мы получаем None в результате выполнения get_message(), так как сообщение было обработано ранее.
Существует три стратегии чтения сообщений.
Заметка: так как мы работаем в отдельном потоке, то обрабатывать сообщения можно только автоматически через обработчик. Таким образом, redis-py запрещает выполнять run_in_thread() если вы подписаны на паттерны или каналы без привязанных обработчиков.
Объект PubSub запоминает на какие каналы он подписан. В случае разрыва соединения, например ошибки сети, этот объект восстанавливает свое исходное состояние. Сообщения опубликованные в момент отключения не будут получены. Когда вы заканчиваете работу с объектом PubSub, необходимо вызвать метод close() для закрытия соединения.
Скрипты LUA
Redis-py поддерживает команды EVAL, EVALSHA и SCRIPT. Хотя существует ряд нюансов при работе с ними. redis-py использует свой объект Script для упрощения работы. Для создания экземпляра скрипта, используйте функцию register_script на стороне клиента передав код LUA в качестве первого параметра. register_script возвращает экземпляр Script, который вы можете использовать дальше в своем коде.
Следующий пример LUA скрипта принимает два параметра: имя ключа и значение множителя. Скрипт выбирает значение ключа, умножает его на значение множителя и возвращает результат.
Объект Script заносит скрипт LUA в кеш Redis. В случае ошибки NOSCRIPT, он загрузит сохраненную версию скрипта и попробует выполнить её. Также объекты Script могут работать с Pipelines. Экземпляр pipeline следует передать при вызове скрипта в качестве аргумента клиента. Автоматически скрипт регистрируется в кеше Redis переде запуском pipeline.
Поддержка Sentinel
Redis-py может работать с Redis Sentinel для обнаружения узлов Redis. Потребуется как минимум одна служба Sentinel. Подключение redis-py к Sentinel довольно просто. Вы можете использовать соединение Sentinel для обнаружения главных и дочерних сетевых адресов.
Вы так же можете создать соединения клиента Redis при помощи экземпляра Sentinel. Можно просто подключиться к главной ветке (при записи) или к дочерней (при операциях чтения).
При попытке подключения к дочернему хосту, пул соединений Sentinel просматривает все возможные соединения пока не найдет тот, к которому можно подключиться. Если нет доступных дочерних хостов, то соединение будет установлено с главным хостом.
Scan итераторы
Redis для начинающих
Введение
С одной стороны есть традиционные ACID реляционные базы данных такие как MySQL, PostgreSQL, Oracle и др. Они надежны и стабильны. Сама аббревиатура ACID описывает требования к транзакционной системе (Atomicity — Атомарность, Consistency — Согласованность, Isolation — Изолированность, Durability — Долговечность). Их основная задаче не просто хранить данные, а хранить с максимальной надежностью. Но их основной недостаток, они очень медленные.
С другой стороны есть очень быстрые хранилища в памяти типа ключ-значение, например memcached. Они очень быстрые за счет предельной простоты и отказа от надежности. Несложно привести несколько примеров задач где нужна производительность даже за счет надежности:
— система мониторинга с n-ым количеством датчиков, которые должны постоянно отправлять данные.
— система логирования действий пользователя на каком нибудь сайте
— контроль трафика сети в реалтайм
— хранение сессий пользователей
и т.д.
Redis относится к третьему типу хранилищей. Когда нужно быстрая обработка данных и при этом сохранялось бы определенный уровень надежности и возможности масштабирования.
Redis (REmote DIctionary Server) — это не реляционная структура данных в памяти, используемая в качестве базы данных. Данные хранятся в виде пары ключ-значение. И при этом хранилище умеет масштабироваться путем репликации между серверами. Redis сохраняет все данные в памяти, что позволяет сделать доступ к данным максимально быстрым по сравнению с другими базами данных. Почему Redis известен своей исключительной высокой производительностью даже среди других key-value хранилищ.
Redis позволяет нам хранить данные в высокоуровневых структурах данных, такие как строки, хэши, списки, наборы. Это дает нам больше гибкости в отношении типа и объема информации, которую мы можем хранить в хранилище данных Redis.
Он также довольно дружелюбен для разработчиков, поскольку поддерживает большинство языков высокого уровня, таких как Python, JavaScript, Java, C / C ++ и PHP.
Установка Redis
Для дальнейшего изучения Redis нам необходимо скачать и установить сервер Redis. Можно использовать инструкции с официальной веб-страницы. Так же под MacOS можно использовать Homebrew, а для Linux что типа apt. Для запуска Redis используется команда redis-server
У Redis есть Redis-CLI (Common Line Interface), который можно использовать для взаимодействия с данными напрямую на сервере Redis.
Чтобы проверить правильность установки Redis, запустите redis-cli, а затем введите команду ping в появившейся подсказке:
Если сервер отвечает ответом PONG значит он готов к работе. По умолчанию сервер Redis работает на порту 6379, что видно в нашем приглашении.
Что бы выйти из redis-cli используйте команду quit.
Для вывода помощи по списку команд в консоли можно использовать команду HELP @string. Для вывода помощи по конкретной команде можно использовать команду HELP APPEND Например:
Далее приведен краткий список самых необходимых команд. Для изучения полного списка команд, если в этом есть необходимость, обратитесь к официальной документации.
Прежде чем начать использовать Redis в любом языке программирования нужно узнать о базовых командах и структурах используемых в Redis.
Команды
Прежде всего Redis это хранилище типа ключ: значение. И самые первые команды которую все изучают, это команды SET и GET:
Команда используется для установки ключа и его значения, с дополнительными необязательными параметрами для указания срока действия записи значения ключа. Давайте установим ключ foo со значением «hello world». Параметр EX указывает время жизни объекта в секундах, PX в милисекундах:
Команда используется для получения значения, связанного с ключом. Если запись значения ключа превысила срок действия, будет возвращено nil:
По умолчанию все значение в Redis сохраняются как строки.
EXISTS
Эта команда проверяет, существует ли что то с данным ключом. Она возвращает 1 если объект существует или 0 если нет. Boolean типа в Redis нет.
FLUSHALL
Эта команда полностью удаляет все данные в текущем сеансе.
GETSET
Команда возвращает текущее значение и устанавливает новое. Используется для атомарного управления данными.
Команда удаляет ключ и соответствующее значение:
APPEND
Команда добавляем в соотвествующий ключ дополнительное значение. Возвращает количество символов итогового значения.
Возвращает все ключи из базы по указанному шаблону. Есть предостережение что в реальных приложения эту команду лучше не использовать из-за того что она очень медленная.
INCR / DECR
Инкремент / декримент. Если значение ключа integer (хотя в базе храниться все равно строка) можно увеличить или уменьшить значение на 1. Если использовать команду INCR с несуществующем значением то создаться новый ключ со значением 1.
Когда ключ установлен с истечением срока действия (например SET foo EX 10), эту команду можно использовать для просмотра оставшегося времени:
PERSIST
Если мы передумаем об истечении срока действия ключа, мы можем использовать эту команду, чтобы удалить период истечения срока действия:
RENAME
Эта команда используется для переименования ключей на нашем сервере Redis:
Комплексные типы данных
Хеш таблицы
Redis позволяет в качестве значения так же использовать ключ: значение. Что по сути будет почти аналогией объектов из JavaScript или словари в Python. Для записи объекта используется команда HSET в следующем формате HSET имя_ключа имя_атрибута значение. Для чтения объекта используется команда HGET в формате HGET имя_ключа имя_атрибута. Команда HGETALL используется для получения
Множества
Не упорядоченная коллекция уникальных элементов. Аналог set в Python. Для добавление нового элемента во множество используется команда SADD. Для получения все элементов используется команда SMEMBERS. SUNION используется для объединение множеств. SDIFF используется для вычитания из первого множества второго. SINTER возвращает общие элементы указаных множеств. SPOP удаляет и возвращает случайный элемент множества.
Упорядоченные множества
Упорядоченная коллекция уникальных элементов. Для добавление нового элемента в упорядоченное множество используется команда ZADD. Формат ZADD имя_ключа порядковое_число_упорядочивания_множества значение
Команда ZRANGE возвращает срез данных множества
Списки
Транзакции в Redis
Обычное определение транзакций для реляционных баз данных означает следующее: транзакции это группа команд с базой данных, которые должны либо полностью выполнится или в случае возникновение ошибки вернуть состояние базы данных в исходное состояние. В Redis то же есть такое понятие как транзакции. Но означает немного другое. Транзакции в Redis это просто последовательное выполнение ранее записаных команд без возможности полноценного возвращения исходного состояния в случае ошибки исполнения.
С помощью команды MULTI можно начать запись команд. Далее введенные команды не исполняются а записываются в буфер. Это будет происходит до ввода команды на исполнения транзакции EXEC. Далее все ранее введенные команды будут исполнены один за другим. Команда DISCARD отмена записи команд транзакций. Если возникнет ошибка в процессе ввода команд вся транзакция не будет выполнена.
Механиз подписок PUS-SUB
Одно из основных преимуществ Redis от других key-value хранилищ заключается в том, что в Redis есть механизм подписок. То есть Redis можно использовать как сервер сообщений.
Одни клиенты подписываются на определенные каналы используя команду SUBSCRIBE имя_канала
Другие клиенты могут отправлять сообщения в этот канал используя команду PUBLISH имя_канала значение
Допустим один клиент подписывается на канал
Другой клиент что то отправляет в этот канал
И в этот момент первый клиент получит это сообщение
Основы применение Redis в Python
Redis очень широко применяется в современной разработке ПО. Библиотеки поддержки есть для любого языка программирования.
Кратко рассмотрим использование Redis в Python. Для этого первым делом загрузим библиотеку поддержки:
Далее подключимся к серверу
И далее можно уже начать попробовать использовать все ранее рассмотренные команды. Надеюсь они будут понятны без дополнительных пояснений:
Заключение
Redis — это мощный и быстрый вариант хранения данных, который при правильном использовании может принести много преимуществ. Он не имеет крутой кривой обучения, поэтому с ним легко начать работать. Также поставляется с удобным инструментом CLI, который помогает нам взаимодействовать с ним с помощью простых и интуитивно понятных команд.
Redis в Python
Nov 9, 2019 · 21 min read
В данном руководстве вы узнаете, как использовать Python с Redis. Redis является высокопроизводительным хранилищем ключей, отличается высокой скоростью работы и широтой областей применения.
Авторы книги Семь баз данных за семь недель отзываются о Redis следующим образом:
Если API для программиста — то же, что удобство работы для пользователя, то Redis следует
поместить в Музей современного искусства рядом с Mac Cube.
И в быстродействии у него практически нет соперников. Чтение производится быстро, а запись еще быстрее — на некоторых эталонных тестах продемонстрировано до 100 000 операций SET в секунду.
Интригует, не так ли? Данное руководство подойдет для программистов Python, которые ранее никогда не работали с Redis. Помимо самого Redis мы подробно изучим его клиентскую библиотеку Python redis-py.
redis-py (импортируется модуль прост о как redis ) — один из множества клиентов Python для Redis. Цитируя разработчиков самого Redis, клиент можно охарактеризовать как будущее для развития Python. Он позволяет вызывать команды Redis из Python и возвращать знакомые объекты Python.
В данном руководстве мы рассмотрим следующие вопросы:
Установка Redis из исходников на Windows, Linux и Mac OS X
Рассмотрим весь процесс установки Redis от А до Я. Начнем с загрузки, далее перейдем к созданию, после чего приступим к самой инсталляции.
Обратите внимание: этот раздел направлен на установку на Mac OS X или Linux. Если вы используете Windows, есть форк, который может быть установлен как Windows Service. Достаточно сказать, что Redis, как программа, вполне комфортно себя чувствует на Linux, а настройка использование в Windows могут быть трудоемкими.
Сначала, загрузим исходный код Redis в виде тарболла (архива):
Опционально — вы можете удалить сам архив:
Команда make install выполняет два действия:
Рассмотрим все шаги:
Настройка Redis на сервере в подробностях
Redis имеет гибкие настройки. Хотя его можно использовать сразу из коробки, мы все же уделим немного времени на настройку базовых конфигураций. Они связаны с сохранением базы данных и безопасностью:
Конфигурация Redis является самодокументированным с примером файла redis.conf, расположенного в исходнике Redis для удобного чтения. Если вы используете Redis в продакшене, будет не лишним уделить особое внимание прочтению примера этого файла для ознакомления с тонкостями Redis и его настройками.
Руководство быстрого запуска Redis также включает в себя раздел, который посвящен более аккуратной настройке Redis, но указанных здесь вариантов настройки будет вполне достаточно для начала работы с Redis.
Минутка безопасности : несколько лет назад создатель Redis отметил уязвимости в ранних версиях Redis в случае, когда отсутствуют настроенные конфигурации. Redis 3.2 (текущая версия — 5.0.3) получил ряд изменений для решения этой проблемы, установив защищенный режим по умолчанию.
С пониманием всего вышеперечисленного, мы можем вникнуть в само использование Redis.
Начало работы с Redis на примерах
В данном разделе будет представлена самая важная информация для начала работы с Redis, а также описаны главные принципы его использования. Redis имеет архитектуру клиент-сервер и пользуется моделью запрос-ответ. Это значит, что вы (клиент) подключаетесь к серверу Redis через TCP подключение, или порт 6379 по умолчанию. Вы запрашиваете определенное действие (какая-либо форма чтения, написания, получения, отправки или обновления), а сервер вам отвечает.
Как правило, к одному и тому же серверу обращается достаточно большое количество клиентов. По существу именно для таких ситуаций создан Redis или любой другой клиент-сервер приложения. Каждый клиент выполняет (обычно это связано с блокировкой) чтение в сокете, ожидая ответ сервера.
Типичный способ выполнить это в разработке — запустить сервер на localhost (адрес IPv4 127.0.0.1 ), который будет выбран по умолчанию, если вы не попросите Redis об обратном. Вы также можете передать redis-server название вашего файла конфигурации, что похоже на указание всех его пар ключей-значений в качестве аргументов командной строки:
Команды Redis нечувствительны к регистру, в отличие от аналогов в Python.
Redis в качестве словаря Python
Redis означает Remote Dictionary Service, другими словами — служба удаленного словаря.
Вы можете спросить: “Типа, как словарь Python?”
Именно. Существует огромное количество параллелей, которые вы можете провести между словарем Python и тем, что из себя представляет Redis:
Создателю Redis Сальваторе Санфилиппо, конечно, может не понравится сравнение базы данных Redis со словарем Python. Он называет проект сервером структуры данных, а не хранилищем значений ключей, таких как memcached.
Соответствующая последовательность операторов в чистом Python будет выглядеть следующим образом:
Redis также позволяет вам настроить и получить множественные пары ключ-значение в одной команде, MSET и MGET соответственно:
В третьем примере команда EXISTS выполняет проверку на наличие существующего ключа, как в примере существует ли файл:
Python имеет ключевое слово in для проверки того же, что связано с dict.__contains__(key) :
Эти несколько примеров нужны, чтобы с использованием нативного Python показать, что происходит на высоком уровне с несколькими командами Redis. В примерах Python нет клиент-серверного компонента, и redis-py еще не вписывается в картину. Это нужно для того, чтобы показать функционал Redis на примере.
Вот краткое описание нескольких команд Redis, которые вы видели, и их функциональных эквивалентов Python:





















