django 学习笔记 使用 redis 缓存加快页面的响应速度-附一个简单的实例

前言:「redis」基于内存的数据库,响应速度到远远快于基于硬盘的「mysql」,使用方式是:直接从「redis」中读取数据,如果「redis」中没有我们需要的数据或者数据更新过,则从「mysql」中读取数据,加载到「redis」中,在将数据返回到前端页面。数据的第一次查询和加载会慢一点,但后面会快很多。


「redis」的配置

「redis」官方并不支持「windows」操作系统,需要通过「Github」获取适配「windows」版本的「redis」

「windows」版本的「redis」下载链接,下载「Redis-x64-3.2.100.msi」就好了,下载完成后,点击安装(默认配置就可以)。

在「管理员权限cmd」中「cd」到你的安装目录:运行「redis-server.exe --service-install redis.windows.conf」将「redis」设置成系统服务。启动服务「net start redis」,停止服务「net stop redis」

连接「redis」:「redis-cli  -h 127.0.0.1 -p 6379」后面跟的参数都是可以自己设置的。默认情况下没有密码的。如果自是本地连接,后面的参数都可省略

默认参数的设置:通过「CONFIG GET」和「CONFIG SET」来获取和设置参数,也可以直接打开安装目录下的「redis-windows.conf」来进行设置。

需要设置的参数:

1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

>>>  daemonize no

2. 绑定的主机地址,如果你想进行远程访问,请在配置文件中将这一行注释掉

>>>  bind 127.0.0.1

3. 设定密码,比如将密码设置成 123456(配置文件中修改)

>>>  requirepass 123456


 「django」中的使用

有大神做好了一个连接二者的模块「django-redis」,只需在你「python」项目的虚拟环境中进行「pip」安装即可。

不过要注意安装的版本哦,如果你用的「django」的版本比较低的话,最新版的「django-redis」会强制更新的「django」。所以最好看一下「django-redis」的文档。链接在这里,里面有中文翻译版的

安装完成后的配置

主要是在「django」项目下的「settings.py」中进行设置。参数什么的按官方文档中的来。下面贴出我的设置:

# 配置 redis 缓存
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "PASSWORD": '123456',
            # 套接字建立连接超时设置为 5 秒
            "SOCKET_CONNECT_TIMEOUT": 5,  # in seconds
            # 套接字连接建立后的读写操作超时设置为 5 秒
            "SOCKET_TIMEOUT": 5,  # in seconds
            # memcached 异常行为
            # 在某些情况下, redis 只作为缓存使用, 当它关闭时如果你不希望触发异常.
            # 这是 memcached backend 的默认行为, 你可以使用 django-redis 模拟这种情况.
            "IGNORE_EXCEPTIONS": True,

        }
    }
}

# 配置 django-redis 缓存后端作为 Django 的 session 后端
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

# 当然,你也可以给所有缓存配置相同的忽略行为:
# DJANGO_REDIS_IGNORE_EXCEPTIONS = True

# 当使用 IGNORE_EXCEPTIONS 或者 DJANGO_REDIS_IGNORE_EXCEPTIONS 参数忽略异常时,
# 你也许会用到 DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS 参数来配置日志异常:
DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
# 如果你想设置指定的 logger 输出异常, 只需要设置全局变量 DJANGO_REDIS_LOGGER 为 logger 的名称或其路径即可.
DJANGO_REDIS_LOGGER = 'memcached.error.logger'

# django-redis 支持永不超时设置. 其表现和 django backend 指定的相同:
# timeout=0 立即过期
# timeout=None 永不超时

# django-redis 支持 redis 分布式锁. 锁的线程接口是相同的, 因此你可以使用它作为替代.
# 使用 python 上下文管理器分配锁的例子:
#
# with cache.lock("somekey"):
#     do_some_thing()

# django-redis 支持使用全局通配符的方式来检索或者删除键.
# 使用通配符搜索的例子
# >>> from django.core.cache import cache
# >>> cache.keys("foo_*")
# ["foo_1", "foo_2"]

# 你可以使用 iter_keys 取代 keys 方法, iter_keys 将返回匹配值的迭代器, 你可以使用迭代器高效的进行遍历.
# >>> from django.core.cache import cache
# >>> cache.iter_keys("foo_*")
# <generator object algo at 0x7ffa9c2713a8>
# >>> next(cache.iter_keys("foo_*"))
# "foo_1"

# 如果要删除键, 使用 delete_pattern 方法, 它和 keys 方法一样也支持全局通配符, 此函数将会返回删掉的键的数量
# 使用 delete_pattern 的例子
# >>> from django.core.cache import cache
# >>> cache.delete_pattern("foo_*")

「redis」默认会有 16 个数据库。默认连接的是第一个库「0 号库」。这是使用的是它的第二个库「1 号库」,你也可以自己设置库的数量和具体使用哪个库。「redis」的客户端通过命令「SELECT」来选着使用哪个库。


简单的应用-留言板的留言功能和留言展示功能

新建应用「message_board」

「models.py」下写个模型类

# _*_ coding: utf-8 _*_

from django.db import models
from django.utils import timezone

class Message(models.Model):
    name = models.CharField(max_length=20, verbose_name='留言者姓名')
    email = models.EmailField(max_length=30, verbose_name='留言者邮箱')
    message = models.TextField(verbose_name='留言内容')
    add_time = models.DateTimeField(default=timezone.now, verbose_name='添加时间')

    class Meta:
        verbose_name = u'留言'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

「views.py」下写连个视图类来处理留言提交和留言的显示

# _*_ coding: utf-8 _*_
import json

from django.shortcuts import render
from django.views import View
from django.core.cache import cache

from .models import Message
from .forms import MessageForm

# 设定一个全局变量来指示数据数据是否有更新,这个写感觉有点问题,但是毕竟简单粗暴,对于这个实例够用
status = False

class GetMessage(View):
    def get(self, request):
        return render(request, 'message_board/get_message.html', {})

    def post(self, request):
        global status
        # 验证填入的邮箱合规
        message_form = MessageForm(request.POST)
        if message_form.is_valid():
            message = Message()
            message.name = request.POST.get('name', '')
            message.email = request.POST.get('email', '')
            message.message = request.POST.get('message', '')
            message.save()
            # 数据更新成功,将标志设为 True
            status = True
            return render(request, 'message_board/get_message.html', {
                'msg': json.dumps('留言提交成功!')
            })
        else:
            return render(request, 'message_board/get_message.html', {
                'msg': json.dumps('留言提交失败,邮箱地址不正确!'),
                'message_form': message_form
            })


class MessageDisplay(View):
    def get(self, request):
        global status
        # 使用 redis 来缓存数据
        # 设定一个 key:用来作为 redis 中的键
        key = 'messages'
        # 判断数据是否更新以及缓存中是否有我们需要的数据
        if not status and cache.has_key(key):
            data = cache.get(key)
        # 没有则从「mysql」中更新数据,并更新缓存
        else:
            data = Message.objects.all()
            cache.set(key, data, timeout=5*60)
            status = False
        return render(request, 'message_board/display_message.html', {
            'messages': data,
        })

我自己在写了两个简单前端页面,展示效果如下:

django 学习笔记 使用 redis 缓存加快页面的响应速度-附一个简单的实例

 留言的展示效果:

django 学习笔记 使用 redis 缓存加快页面的响应速度-附一个简单的实例