Redis в Django
В современную эпоху технологий данные становятся все более ценным товаром, и это требует оптимизации хранения и доступа к этим данным. Существует довольно много известных решений для хранения данных, включая системы управления реляционными базами данных (RDBMS), такие как MySQL и PostgreSQL, которые хранят данные в структурированном формате, используя строки и столбцы, а также взаимосвязи внутри данных. Помимо СУБД, существуют хранилища ключей и значений, которые хранят данные на основе уникальных ключей и значений, таких как словарь. Базы данных ключ-значение относятся к семейству баз данных NoSQL, которые не соответствуют реляционной природе СУБД. В этой статье мы рассмотрим Redis как хранилище ключей и значений и используем его в проекте для изучения его функциональности.
Что такое Redis и зачем его использовать?
Redis (удаленный сервер словарей) - это хранилище структур данных в памяти, которое может использоваться в качестве базы данных, кэша или посредника сообщений.
Данные хранятся в Redis в электронная форма ключей-значений, в которой ключи используются для поиска и извлечения данных, хранящихся в экземпляре Redis.
Обычные базы данных хранят данные на диске, что приводит к дополнительным затратам времени и аппаратных ресурсов. Redis позволяет избежать этого, сохраняя все данные в памяти, что делает их легкодоступными и увеличивает скорость доступа к данным и манипулирования ими по сравнению с обычными базами данных.
Именно по этой причине Redis известен своей исключительной производительностью.
Redis позволяет нам хранить данные в нескольких высокоуровневых структурах данных, включая строки, хэши, списки, наборы и отсортированные наборы. Это дает нам больше гибкости в отношении типа и объема информации, которую мы можем хранить в хранилище данных Redis. Будучи написанным на ANSI C, Redis является легким и не имеет внешних зависимостей.
Он также довольно удобен для разработчиков, поскольку поддерживает большинство языков высокого уровня, таких как Python, JavaScript, Java, C / C++ и PHP.
Когда вам следует использовать Redis?
Распространенные варианты использования Redis включают де:
- Кэширование: Учитывая его скорость по сравнению с традиционными базами данных, с точки зрения операций чтения и записи, Redis стал идеальным решением для временного хранения данных в кэше для ускорения доступа к ним в будущем.
- Организация очереди сообщений: Благодаря возможности реализации парадигмы обмена сообщениями "Публикация/подписка" Redis стал посредником сообщений для систем организации очереди сообщений.
- Хранение данных: Redis можно использовать для хранения данных типа ключ-значение в виде базы данных NoSQL.
Такие компании, как Twitter, Pinterest, Github, Snapchat и StackOverflow, используют Redis для хранения и обеспечения высокой доступности данных для своих пользователей.
Например, Twitter сохраняет самые последние входящие твиты для пользователя в Redis, чтобы ускорить доставку твитов в клиентские приложения.
Pinterest использует Redis для хранения списка пользователей и досок объявлений, на которые подписан пользователь, списка подписчиков пользователя и списка людей, которые подписаны на ваши доски объявлений, а также других списков для улучшения работы платформы.
Redis с помощью Django
Чтобы продемонстрировать, как интегрировать Redis в веб-приложение, мы создадим API с использованием Django и Django REST, который может получать пару ключ-значение и сохранять ее на нашем сервере Redis.
Наш API также сможет извлекать значения для заданных ключей, извлеките все сохраненные пары ключ-значение, а также удалите запись ключ-значение.
Давайте начнем с создания папки для размещения нашего проекта:
$ mkdir redis_demo && cd $_
Затем давайте создадим виртуальную среду и активируем ее:
$ virtualenv --python=python3 env --no-site-packages
$ source env/bin/activate
И, наконец, давайте установим необходимые библиотеки:
$ pip install django djangorestframework redis
API нашего приложения будет получать запросы и взаимодействовать с нашим сервером Redis, используя библиотеку Redis-py.
Давайте теперь создадим приложение:
# Create the project
$ django-admin startproject django_redis_demo
$ cd django_redis_demo
# Create the app
$ django-admin startapp api
# Migrate
$ python manage.py migrate
Чтобы убедиться, что наша настройка Django прошла успешно, мы запускаем сервер:
$ python manage.py runserver
Когда мы переходим к http:127. 0. 0. 1:8000 , нас приветствуют.
Следующим шагом является добавление нашего api-приложения и Django REST в наш проект путем обновления списка INSTALLED_APPS, найденного в django_redis_demo/settings. py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Add these two
'rest_framework',
'api',
]
Redis-py нуждается в запущенном экземпляре Redis для взаимодействия. Нам нужно будет настроить это в наших django_redis_demo/settings.py путем добавления:
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
С помощью этого параметра мы также можем использовать экземпляр Redis, запущенный внутри контейнера Docker, или удаленный экземпляр Redis, даже если в этом случае нам может потребоваться предоставить данные аутентификации. На данный момент мы будем использовать наш локальный экземпляр Redis, подробную настройку в рамках данной статьи мы рассматривать не будем, что бы не усложнять статью, в интернете можно найти настройку, там ничего сложного.
Далее мы собираемся создать маршрут, который будет использоваться для доступа изучите наш API и свяжите его с нашим основным приложением Django. Сначала мы создадим пустой api/urls. py файл, затем создаем наш путь в django_redis_demo/urls.py:
# Modify this import
from django.urls import path, include
urlpatterns = [
...
# Add this entry
path('api/', include('api.urls')),
]
Все запросы, поступающие через api / конечную точку, теперь будут обрабатываться нашим api-приложением. Чего сейчас не хватает, так это представлений, которые будут обрабатывать запросы.
Наши представления будут простыми представлениями на основе функций, которые позволят нам взаимодействовать с сервером Redis. Сначала давайте создадим URL-адреса, с которыми мы будем взаимодействовать в нашем api/urls.py:
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from .views import manage_items, manage_item
urlpatterns = {
path('', manage_items, name="items"),
path('<slug:key>', manage_item, name="single_item")
}
urlpatterns = format_suffix_patterns(urlpatterns)
Первый путь позволит нам создавать записи и соперничать w все записи, в то время как второй путь даст нам детальное управление отдельными записями.
У нас будет два представления на основе функций: manage_items() и manage_item(), которые будут обрабатывать запросы и взаимодействовать с нашим экземпляром Redis. Они оба будут проживать в нашем api/views. py файл.
Чтобы лучше объяснить код, мы разобьем его на более сжатые фрагменты. Если вы хотите увидеть полный код, в конце этой статьи есть ссылка на репозиторий GitHub с исходным кодом.
Мы начнем с импорта необходимых библиотек и подключения к нашему экземпляру Redis:
import json
from django.conf import settings
import redis
from rest_framework.decorators import api_view
from rest_framework import status
from rest_framework.response import Response
# Connect to our Redis instance
redis_instance = redis.StrictRedis(host=settings.REDIS_HOST,
port=settings.REDIS_PORT, db=0)
Здесь мы создаем наш объект подключения, передавая узел Redis и порт, как было сконфигурировано ранее. красный в нашем r django_redis_demo/settings. py.
Затем мы создаем наше первое представление manage_items(), которое будет использоваться для извлечения всех элементов, установленных в данный момент в нашем запущенном экземпляре Redis. Это представление также позволит нам создавать новые записи в нашем экземпляре Redis, передавая объект JSON:
@api_view(['GET', 'POST'])
def manage_items(request, *args, **kwargs):
if request.method == 'GET':
items = {}
count = 0
for key in redis_instance.keys("*"):
items[key.decode("utf-8")] = redis_instance.get(key)
count += 1
response = {
'count': count,
'msg': f"Found {count} items.",
'items': items
}
return Response(response, status=200)
elif request.method == 'POST':
item = json.loads(request.body)
key = list(item.keys())[0]
value = item[key]
redis_instance.set(key, value)
response = {
'msg': f"{key} successfully set to {value}"
}
return Response(response, 201)
Затем давайте определим manage_item():
@api_view(['GET', 'PUT', 'DELETE'])
def manage_item(request, *args, **kwargs):
if request.method == 'GET':
if kwargs['key']:
value = redis_instance.get(kwargs['key'])
if value:
response = {
'key': kwargs['key'],
'value': value,
'msg': 'success'
}
return Response(response, status=200)
else:
response = {
'key': kwargs['key'],
'value': None,
'msg': 'Not found'
}
return Response(response, status=404)
elif request.method == 'PUT':
if kwargs['key']:
request_data = json.loads(request.body)
new_value = request_data['new_value']
value = redis_instance.get(kwargs['key'])
if value:
redis_instance.set(kwargs['key'], new_value)
response = {
'key': kwargs['key'],
'value': value,
'msg': f"Successfully updated {kwargs['key']}"
}
return Response(response, status=200)
else:
response = {
'key': kwargs['key'],
'value': None,
'msg': 'Not found'
}
return Response(response, status=404)
elif request.method == 'DELETE':
if kwargs['key']:
result = redis_instance.delete(kwargs['key'])
if result == 1:
response = {
'msg': f"{kwargs['key']} successfully deleted"
}
return Response(response, status=404)
else:
response = {
'key': kwargs['key'],
'value': None,
'msg': 'Not found'
}
return Response(response, status=404)
manage_item() предоставляет нам доступ к отдельным записям в нашем экземпляре Redis. Это представление требует, чтобы вызывающий абонент передал ключ нужного нам элемента в URL-адресе.
Затем этот ключ используется для определения местоположения значения, сохраненного в нашем экземпляре. Используя метод PUT HTTP и передавая новое значение ключа, мы можем обновить значение ключа.
С помощью метода DELETE мы можем удалить пару ключ-значение из нашего экземпляра Redis.
Чтобы увидеть наш API в действии, мы будем использовать Postman. Но сначала давайте создадим одну или две записи с помощью инструмента redis-cli:
$ redis-cli
127.0.0.1:6379> SET HELLO "WORLD"
OK
127.0.0.1:6379> SET REDIS "DEMO"
OK
После настройки данных, давайте отправим запрос GET на localhost:8000/api/items:
Наш API способен извлекать все пары ключ-значение в нашем текущем экземпляре Redis. Давайте теперь отправим POST-запрос со следующей полезной нагрузкой по тому же URL-адресу:
{
"mighty": "mug"
}
Давайте отправим другой запрос GET в ту же конечную точку:
Мы видим, что ключ, который мы созданный с использованием нашего API, сохраняется в нашем экземпляре Redis. Мы можем проверить его существование с помощью инструмента CLI.
Давайте теперь протестируем вторую конечную точку, которая возвращает значение одного ключа, отправив запрос GET на http://localhost:8000/api/items/HELLO:
Все прошло хорошо. Давайте теперь обновим значение, связанное с ключом HELLO, отправив следующий JSON через запрос PUT в ту же конечную точку:
{
"new_value": "stackabuse.com"
}
Когда мы достанем ключ, еще раз здравствуйте:
Наше значение было успешно обновлено. Последний оставшийся шаг - это удаление ключей, поэтому давайте продолжим и отправим запрос на удаление по адресу http://localhost:8000/api/items/HELLO чтобы удалить ключ, который мы только что обновили.
Когда мы пытаемся получить доступ к тому же элементу после его удаления:
Нам сообщают, что наш ключ был удален. Наш Django API успешно взаимодействовал с нашим экземпляром Redis, используя библиотеку Redis-py.
Вывод
Redis - это мощный и быстрый способ хранения данных, который при правильном использовании может принести много пользы. У него нет крутой кривой обучения, поэтому его легко освоить, и он также поставляется с удобным CLI-инструментом, который помогает нам взаимодействовать с ним с помощью простых и интуитивно понятных команд.
Мы смогли легко интегрировать наш Django API с локально запущенным экземпляром Redis, что свидетельствует о его простоте использования с распространенными языками программирования высокого уровня.