如何在 Django 应用程序中使用 Redis 进行缓存
减轻服务器压力的方法之一是缓存数据。 这是通过在处理数据后缓存数据,然后在下次请求时从缓存中提供数据来完成的。 本篇文章将详细讨论 Redis,解释如何在 Python 应用程序中安装 Redis 和缓存数据。
Redis 和缓存简介
缓存是指将服务器的响应存储在客户端本身,这样客户端就不需要一次又一次地向服务器请求同一个资源。 服务器响应应该包含有关如何进行缓存的信息,以便客户端缓存响应一段时间或从不缓存服务器响应。
另一方面,缓存是用于存储数据的硬件或软件组件,因此可以更快地满足未来对相同数据的请求。
在这个用户期望在一秒内得到结果的时代,明智的做法是通过从缓存中读取数据来服务请求,这最终比从较慢的数据存储中读取更快; 因此,系统性能取决于有多少请求可以从缓存中得到服务。
Redis 是一种开源的内存数据结构存储,用作数据库、缓存和消息代理。 它通过将数据存储在缓存中并在下次请求时提供它来工作,而不是每次都查询数据库。
安装Redis
Redis 已经包含在 Ubuntu 的官方软件包存储库中。 要安装最新版本的 Redis 服务器,请依次运行以下命令。
$ sudo apt-get update
$ sudo apt install redis
安装 Redis 后,我们可以使用以下命令检查其版本:
$ redis-cli --version
如果我们使用的是 Windows,则可以使用适用于 Linux 的 Windows 子系统(也称为 WSL2)运行 Redis。 WSL2 基本上允许我们直接在 Windows 机器上运行 Linux 环境(命令行工具、实用程序、应用程序等)。
要在 Windows 上安装和运行 Redis,我们首先需要在本地 Powershell 终端上运行以下命令以启用适用于 Linux 的 Windows 子系统(确保我们以管理员身份运行此命令):
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
接下来,在 Windows 机器上打开 Microsoft Store,搜索 Ubuntu 并安装它。 这使我们可以访问 Ubuntu 终端,我们将在该终端运行安装 Redis 的命令。
安装 Ubuntu 后,启动终端并输入我们的 UNIX 用户名和密码。 然后依次运行这些命令来安装Redis:
$ sudo apt-add-repository ppa:redislabs/redis
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install redis-server
运行以下命令以启动服务器:
$ sudo service redis-server restart
Django API 示例
让我们创建我们的 Django 项目。 我们的项目将能够缓存商店中的所有产品,以便在后续查询中轻松快速地检索数据。
要在我们的应用程序中使用 Redis,我们需要执行以下操作:
- 检查缓存中是否存在当前查询的结果。
- 如果缓存中存在结果,则检索它们。
- 如果结果不存在,则获取它们,将它们存储在缓存中,然后将它们转发给请求实体。
要求
- Django
- django-redis
- Redis
- loadtest
创建项目
在我们开始之前,创建一个目录并安装一个虚拟环境。 虚拟环境可让我们安装应用程序所需的库版本。
$ mkdir myprojects
$ cd myprojects
接下来,激活虚拟环境并安装项目要求。
$ source venv/bin/activate
$ pip install django==1.9
$ pip install django-redis
$ pip install djangorestframework
创建 Django 项目
$ django-admin startproject django_cache
创建一个名为 store 的新应用程序,它将处理我们商店中的产品管理。
$ cd django_cache
$ python manage.py startapp store
将商店应用程序和 rest_framework 添加到 settings.py 文件中的已安装应用程序列表中。
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'store', # add here
'rest_framework', # add here too
]
创建模型
在 store/models.py 中,我们首先创建用于存储产品详细信息的产品模型,如下所示:
from __future__ import unicode_literals
from django.db import models
import datetime
# Create your models here.
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
price = models.IntegerField(null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, blank=True)
date_modified = models.DateTimeField(auto_now=True, blank=True)
def __unicode__(self):
return self.name
def to_json(self):
return {
'id': self.id,
'name': self.name,
'desc': self.description,
'price': self.price,
'date_created': self.date_created,
'date_modified': self.date_modified
}
迁移
为我们的产品模型创建一个初始迁移,并第一次同步数据库。
$ python manage.py makemigration store
$ python manage.py migrate
创建超级用户
创建一个超级用户,登录到管理面板,并使用我们将用于进行测试的一些示例数据填充我们的数据库。
$ python manage.py createsuperuser
在 Python 应用程序中配置 Redis
为了在 Django 应用程序中使用 Redis,我们需要设置 Redis 来存储应用程序的缓存数据。 以及我们的 settings.py 文件中的以下内容:
settings.py
CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', } } }
接下来,我们将创建一个端点,用于从我们的数据库中检索所有产品。 我们将首先根据从数据库检索数据而不缓存数据需要多长时间来测试应用程序的性能。 然后,我们将实现另一个从缓存中检索数据并比较性能的端点。
在 store/views.py 中,添加以下代码以检索数据库中存在的所有产品。
store/views.py
from django.shortcuts import render from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status # Create your views here. @api_view(['GET']) def view_books(request): products = Product.objects.all() results = [product.to_json() for product in products] return Response(results, status=status.HTTP_201_CREATED)
配置 URL
创建文件 store/urls.py 并添加以下代码。
store/urls.py
from django.conf.urls import url from .views import view_books urlpatterns = [ url(r'^$', view_books), ]
我们还需要将用户应用程序中的 URL 导入到主 django_cache/urls.py 文件中。
django_cache/urls.py
from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^store/', include('store.urls')) ]
让我们做一个测试,看看我们是否走上正轨。 我们将使用负载测试。 如果大家不熟悉 loadtest,它是一个测试性能的工具。
以 root 身份安装 loadtest 很简单:
$ sudo npm install -g loadtest
$ loadtest -n 100 -k https://localhost:8000/store/
# result
INFO Requests per second: 55
从上面可以看出,每秒处理 55 个请求。
让我们创建另一个端点,用于在使用 Redis 缓存后检索数据。 编辑 users/views.py :
users/views.py
from rest_framework.decorators import api_view from rest_framework import status from rest_framework.response import Response from django.core.cache import cache from django.conf import settings from django.core.cache.backends.base import DEFAULT_TIMEOUT CACHE_TTL = getattr(settings, 'CACHE_TTL', DEFAULT_TIMEOUT) from .models import Product # Create your views here. @api_view(['GET']) def view_books(request): # rest of the code @api_view(['GET']) def view_cached_books(request): if 'product' in cache: # get results from cache products = cache.get('product') return Response(products, status=status.HTTP_201_CREATED) else: products = Product.objects.all() results = [product.to_json() for product in products] # store data in cache cache.set(product, results, timeout=CACHE_TTL) return Response(results, status=status.HTTP_201_CREATED)
上面的代码将检查缓存中是否存在关键产品,如果找到,则表示的数据将返回给浏览器。 如果缓存中没有数据,我们先从数据库中取出数据,存入缓存中,然后将查询到的数据返回给浏览器。
更新 store/urls.py 如下。
store/urls.py
from django.conf.urls import url from .views import view_books, view_cached_books urlpatterns = [ url(r'^$', view_books), url(r'^cache/', view_cached_books), ]
让我们进行测试。
$ loadtest -n 100 -k http://localhost:8000/store/cache/
# results
INFO Requests per second: 233
第一次访问端点 localhost:8000/store/cache
时,应用程序将从数据库中查询并返回数据,但随后对该 URL 的调用将绕过数据库并从缓存中查询,因为数据已经在缓存中可用 。
总结
在本篇文章中,我们使用 Redis 为应用程序提升了速度。 我们利用 Redis 中的 RAM 来存储查询结果,然后在后续查询中从缓存中返回这些结果,而不是往返于数据库。
还有其他可用的缓存工具,例如类似于 Redis 的 Memcached。 然而,Redis 比 Memcached 更受欢迎,因为它只需几分钟即可设置并在应用程序中运行。 Redis 具有更复杂的机制,因为它被描述为“数据结构存储”,因此使其更加强大和灵活。 Redis 还有一个更大的优势,因为你可以存储任何形式的数据。
希望本篇文章向大家展示了应用程序添加缓存层从而提高性能是多么容易。 当我们需要减少加载时间和服务器成本时,必须考虑缓存。
相关文章
Django 中的 Slug
发布时间:2023/05/04 浏览次数:173 分类:Python
-
本篇文章旨在定义一个 slug 以及我们如何使用 slug 字段在 Python 中使用 Django 获得独特的帖子。
在 Django 中按降序过滤查询集中的项目
发布时间:2023/05/04 浏览次数:157 分类:Python
-
在这个讲解中,学习如何借助 Django 中的 order_by() 方法按降序过滤出查询集中的项目。
Django ALLOWED_HOSTS 介绍
发布时间:2023/05/04 浏览次数:181 分类:Python
-
本文展示了如何创建您的 Django 网站,为公开发布做好准备,如何设置 ALLOWED_HOSTS 以及如何在使用 Django 进行 Web 部署期间修复预期的主要问题。
Django 中的 Select_related 方法
发布时间:2023/05/04 浏览次数:129 分类:Python
-
本文介绍了什么是查询集,如何处理这些查询以及我们如何利用 select_related() 方法来过滤 Django 中相关模型的查询。
使用 Post 请求将数据发送到 Django 服务器
发布时间:2023/05/04 浏览次数:159 分类:Python
-
在这篇关于Django的讲解中,我们简要介绍了post和get请求以及如何在Django中用post实现CSRF token。
Django 返回 JSON
发布时间:2023/05/04 浏览次数:106 分类:Python
-
在与我们的讨论中,我们简要介绍了 JSON 格式,并讨论了如何借助 Django 中的 JsonResponse 类将数据返回为 JSON 格式。
在 Django 中创建对象
发布时间:2023/05/04 浏览次数:59 分类:Python
-
本文的目的是解释什么是模型以及如何使用 create() 方法创建对象,并了解如何在 Django 中使用 save() 方法。
在 Django 中为多项选择创建字段
发布时间:2023/05/04 浏览次数:75 分类:Python
-
在本文中,我们将着眼于为多项选择创建一个字段,并向您展示如何允许用户在 Django 中进行多项选择。