我的博客网站搭建: 使用Redis缓存提速
Redis数据库是为了做服务器缓存。以下两种情况都适合使用服务器缓存:
1)数据非经常更新。若每次都从硬盘读取一次,浪费服务器资源、拖慢响应速度。
2)数据更新频率较高,服务器负担比较大。
我网站就有这么一些数据:7日阅读排行榜和七天阅读量变化表。
这些数据只需每天更新一次。而我每次都从数据库获取相应的数据,计算统计排行情况和阅读数。很明显浪费服务器资源,浪费时间。解决方法是定时统计一次数据,保存到数据库或文件中。每次读取数据从中获取。
若保存到数据库,还需要额外建立一张对应的表存储数据。在Django中建立表通常做法是建立一个模型。看似简单,问题调试麻烦、开发时长久。所以我一直拖着没处理该问题。毕竟一开始访问量不是很多。后来不少网友访客打开慢(当然服务器在国外也是个原因),查了资料发现Redis内存数据库。可以将数据写入到内存,再进行读写。减少计算量,可以有效提高服务器响应速度。
这么一来,我就不用创建新表创建模型。直接将数据写入缓存,定时更新。获取数据从服务器缓存获取即可。
啰嗦了这么多,看看如何实现Redis数据库作服务器缓存。
1、安装redis
具体安装过程,见Redis在CentOS7和Windows的安装过程。
读写数据之前,记得开启redis服务。否则会显示No connect未连接错误。
redis-server
2、安装django-redis和settings配置
执行命令,即可安装:
pip install django-redis
目前django-redis已更新到4.10.0版本。安装完毕之后,给Django项目的settings.py文件添加如下配置。
CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis:127.0.0.1:6379', "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", }, }, }
另外,LOCATION参数和你的redis.conf文件中IP地址和端口要一致。redis服务才能监听到你的读写操作。
3、测试redis缓存
该步骤非必须,只是为了测试看可否正常使用redis。
进入django的后台命令模式:
python manage.py shell
逐条输入如下命令测试:
from django.core.cache import cache #引入缓存模块 cache.set('k', '12314', 30*60) #写入key为k,值为12314的缓存,有效期30分钟 cache.has_key('k') #判断key为k是否存在 cache.get('k') #获取key为k的缓存
测试没问题,则说明可正常使用。
若出现错误:ConnectionError: Error 10061 connecting to None:6379。说明没开启redis。
4、redis缓存功能开发
这里需要考虑两个问题:
1)写入redis的数据是什么形式?
2)缓存时效多长?
redis支持字符串、列表、集合、字典等数据结构。经测试,可将Python的字典和列表直接存储。你也可以用json模块对字典和列表转化成字符串再存储。
至于缓存时效看具体情况,建议30分钟或者1小时更新一次。原本我考虑1天更新1次数据,但全球有很多个时区。不是每个时区都和我一样在0点的时候看到更新结果。我们是东八区,我们0点的时候,东九区是1点。所以,每1小时更新一次的频率较为合适,你可以直接设置60*60秒。而我需要整点的时候更新,需要再多一步计算到下一个整点还有多少秒。
获取多少天之前的阅读排行榜代码如下(该部分可以不看):
#获取七天内的阅读排行榜 def get_seven_days_hot_data(): today = timezone.now().date() seven_days_before = today - datetime.timedelta(days=7) blogs = Blog.objects.filter(read_details__date__lte=today,read_details__date__gte=seven_days_before)\ .values('id','title')\ .annotate(read_num_sum=Sum('read_details__read_num'))\ .order_by('-read_num_sum') return blogs[:7]
这是我自己项目的具体代码,主要获取博客id,博客标题,和博客在这段时间内的阅读数。结果返回一个列表。
读写redis缓存代码(敲黑板,这是重点):
from django.core.cache import cache # 获取7天热门博客的缓存数据 hot_data_for_7_days = cache.get('hot_data_for_7_days') if hot_data_for_7_days is None: # 不存在,则获取数据,并写入缓存 hot_data_for_7_days = get_7days_hot_data() # 写入缓存 cache.set('hot_data_for_7_days', hot_data_for_7_days, 3600)
使用has_key方法判断键是否存在;get方法获取数据;set方法设置缓存。
得到该数据,再返回给前端页面:
from django.shortcuts import render content['hot_data_for_7_days'] = hot_data_for_7_days return render(request,"home.html",content)
该方法是示例代码,还需要设置url路由,令其可在前端打开。
前端页面可以用for循环遍历列表,可用键名当作属性获取字典的值。例如:
{% for hot_data in hot_data_for_7_days %}
    <li><a href="{% url 'blog_detail' hot_data.id %}">{{ hot_data.title }}</a>({{ hot_data.read_num_sum }})</li>
{% empty %}
    <li>过去一周暂时没有热门博客</li>
{% endfor %}
其中,hot_data变量是一个字典,键有id、title、read_num_sum。上面代码有写。在模版中,可用属性的方法获取键值。
若你想看看redis保存该数据的样子,可进入redis客户端查看。输入命令redis-cli进入客户端。
再分别输入keys * 查看有那些键,再输入get命令获取数据。结果如下:
 
当然,这里我写入redis缓存是被动写入。需要打开前端页面触发该行为。
所以打开页面正好需要写入缓存时,该页面打开速度相对慢一点。有了缓存之后,后面打开速度飞快。经测试,这一点改动,打开首页足足加快了0.5-1秒。
后面,我将采用celery定时任务主动更新缓存。

                
            
        
浙公网安备 33010602011771号