如何在Django应用程序中使用Redis缓存
减轻服务器压力的方法之一是缓存数据。这是通过在数据被处理后缓存数据,然后在下一次请求时从缓存中提供数据来完成的。本教程将详细讨论Redis,解释如何在Python应用程序中安装Redis和缓存数据。
Redis和缓存简介
缓存是指将服务器响应存储在客户机本身中,这样客户端就不必一次又一次地对同一资源提出服务器请求。服务器响应应该包含有关如何进行缓存的信息,这样客户端就可以缓存响应一段时间,或者永远不会缓存服务器响应。
另一方面,缓存是用于存储数据的硬件或软件组件,因此可以更快地处理对相同数据的未来请求。
在这个用户期望在一秒钟内得到结果的时代,明智的做法是从缓存中读取数据,这最终比从较慢的数据存储区读取数据要快;因此,系统性能取决于可以从缓存中处理多少请求。
redis是一个开放源码的内存数据结构存储,用作数据库、缓存和消息代理.它的工作方式是将数据存储在缓存中,并在下次请求时提供数据,而不是每次查询数据库。
安装Redis
第一步是让Redis在您的机器上在本地运行。安装Redis的最简单方法是通过操作系统的包管理器,如下所示:
|
1
|
sudo
apt-get ``install
redis-server
|
您还可以按照官方Redis站点的说明进行操作。
下载并解压缩Redis 4.0.6 tar如下:
|
1
2
3
|
$ wget http:``//download``.redis.io``/releases/redis-4``.0.6.``tar``.gz
$ ``tar
xzf redis-4.0.6.``tar``.gz
$ ``cd
redis-4.0.6 $ ``make
|
现在编译的二进制文件在src目录中可用。运行Redis:
|
1
|
$ src``/redis-server
|
您可以使用内置客户端与Redis交互:
|
1
2
3
|
$ src``/redis-cli
redis ``set
foo bar OK redis
get foo ``"bar"
|
若要检查redis服务器是否正在运行,请在终端上发出以下命令:
|
1
2
|
$ ``sudo
redis-server
* Ready to accept connections
|
广告
Django API示例
让我们创建Django项目。我们的项目将能够将所有产品缓存在一个存储中,从而使在后续查询中检索数据变得简单和快速。
要在我们的应用程序中使用Redis,我们需要执行以下操作:
- 检查缓存中是否存在当前查询的结果。
- 如果缓存中存在结果,则检索它们。
- 如果结果不存在,获取它们,将它们存储在缓存中,然后将它们转发给请求实体。
所需
- 姜戈
- 姜戈红
- 雷迪斯
- 载荷试验
创建项目
在开始之前,创建一个目录并安装一个虚拟环境。虚拟环境将允许您安装应用程序所需的库版本。
|
1
2
3
|
mkdir
myprojects
cd
myprojects
|
接下来,激活虚拟环境并安装项目需求。
|
1
2
3
4
5
6
7
|
source
venv``/bin/activate
pip ``install
django==1.9
pip ``install
django-redis
pip ``install
djangorestframework
|
创建Django项目
|
1
|
django-admin startproject django_cache
|
创建一个名为Store的新应用程序,它将处理我们商店的产品管理。
|
1
2
3
|
cd
django_cache
python manage.py startapp store
|
将存储应用程序和REST_Framework添加到已安装的应用程序列表中。settings.py
档案。
|
01
02
03
04
05
06
07
08
09
10
11
|
# 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
,我们首先创建用于存储产品详细信息的产品模型,如下所示:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
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
}
|
迁徙
为我们的产品模型创建一个初始迁移,并首次同步数据库。
|
1
2
3
|
python manage.py makemigration store
python manage.py migrate
|
创建超级用户
创建一个超级用户,登录到管理面板,并使用一些示例数据填充数据库,我们将使用这些数据进行测试。
|
1
|
python manage.py createsuperuser
|
在Python应用程序中配置Redis
为了在Django应用程序中使用Redis,我们需要设置Redis来存储应用程序的缓存数据。以下是你的settings.py
档案:
|
1
2
3
4
5
6
7
8
9
|
CACHES ``=
{
'default'``: {
'BACKEND'``:``'django_redis.cache.RedisCache'``,
'LOCATION'``:``'[redis://127.0.0.1:6379/](redis://127.0.0.1:6379/)'``,
'OPTIONS'``: {
'CLIENT_CLASS'``:``'django_redis.client.DefaultClient'``,
}
}
}
|
接下来,我们将创建一个从数据库中检索所有产品的端点。我们将首先测试应用程序在不缓存数据的情况下从数据库中检索数据所需的时间。然后,我们将实现另一个端点,它从缓存中检索数据并比较性能。
在……里面store/views.py
,添加以下代码,检索数据库中的所有产品。
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
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
并添加以下代码。
|
1
2
3
4
5
6
7
8
|
# store/urls.py
from
django.conf.urls ``import
url
from
.views ``import
view_books
urlpatterns ``=
[
url(r``'^$'``, view_books),
]
|
我们还需要将URL从用户应用程序导入到django_cache/urls.py
档案。
|
1
2
3
4
5
6
7
8
9
|
# 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'``))
]
|
让我们做一个测试,看看我们是否在轨道上。我们会用载荷试验...如果您不熟悉负载测试,那么它是测试性能的工具。
将加载测试安装为root很简单:
|
1
|
sudo
npm ``install
-g loadtest
|
|
1
2
3
4
|
$ loadtest -n 100 -k http:``//localhost``:8000``/store/
# result
INFO Requests per second: 55
|
从上面可以看出,每秒处理55个请求。
让我们在使用Redis缓存之后创建另一个用于检索数据的端点。编辑users/views.py
匹配以下内容:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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
详情如下。
|
1
2
3
4
5
6
7
8
9
|
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),
]
|
我们来做测试吧。
|
1
2
3
4
|
$ loadtest -n 100 -k http:``//localhost``:8000``/store/cache/
# results
INFO Requests per second: 233
|
当您第一次访问端点localhost:8000/store/cache时,应用程序将从数据库查询并返回数据,但随后对URL的调用将绕过数据库并从缓存中查询,因为缓存中已经有数据可用。
结语
在本教程中,我们使用Redis给应用程序提供速度的错觉。我们利用Redis中的RAM存储查询结果,然后在后续查询中从缓存中返回这些结果,而不是往返数据库。
还有其他可用的缓存工具,比如memcached,类似于Redis。然而,Redis比memcached更受欢迎,因为在应用程序中设置和工作只需几分钟。Redis具有更复杂的机制,因为它被描述为“数据结构存储”,从而使其更加强大和灵活。Redis还具有更大的优势,因为您可以以任何形式存储数据。
希望本教程向您展示了在应用程序中添加缓存层是多么容易,从而提高了性能。当您需要减少加载时间和服务器成本时,必须考虑缓存。