Работа с 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, что свидетельствует о его простоте использования с распространенными языками программирования высокого уровня.