当数据库资源较多时,有些数据不是经常更新,或者更新较少的时候,我们为了降低服务器的压力可以使用cache缓存系统,而不是每次都去数据库进行查询,这样能够降低不少数据库压力,例如,导航、热门关键词排行等,这些基本很少去更新,所以我们都可以缓存到内存中,这样读取速度快,并且减少了数据库和CPU的压力
Flask框架一般都是使用flask_cache模块来缓存
安装方法是
pip install flask_cache
安装好以后,我们在我们的项目里面实例化一下就可以开始使用了。
from flask_cache import Cache cache = Cache(app,config={'CACHE_TYPE': 'simple'})
然后就是这个对象下的几个装饰器讲解下
1.@cache.cached()装饰器
1).缓存视图函数
使用@cache.cached()装饰器,这个装饰器默认使用request.path作为cache_key,这个cache_key目前我用只是在删除的时候来使用下,应该还有其他用处,这里暂不扩展开来讲解
@cache.cached()装饰器还可以接收参数,如参数timeout设置缓存过期时间;参数unless接收一个Bool类型的值,如果设置为True将不会使用缓存机制;参数key_prefix替换默认的cache_key
2).缓存其他函数
使用@cache.cached()装饰器可以缓存其它非视图相关函数的结果,当使用@cache.cached()装饰器缓存非视图相关函数的结果时,建议传入参数key_prefix来替换默认的cache_key,否则它将会默认使用request.path作为cache_key
2.@cache.memoize()装饰器
在@cache.memoize()装饰器中,函数的参数也包含在cache_key中
上面讲的有点难懂,我简单的理解为,缓存视图函数可以使用@cache.cached()这个装饰器,注意要设置key_prefix
缓存普通函数,不带参数就和@cache.cached()一样,如果带参数就用@cache.memoize()装饰器
如果函数不接受参数那么@cache.cached()和@cache.memoize()就是一样的。
直接上我的实例代码:
#!/usr/local/bin/python3 #coding:utf-8 __author__ = 'merci' from flask import Flask,Blueprint,request,jsonify,render_template from urllib import request as rq from aip import AipNlp from common import formatTime,getThumb,getPage from flask_cache import Cache from model.mysql import database import pymysql import math import json app = Flask(__name__) #定义手机版蓝图 wap = Blueprint('wap', __name__) cache = Cache(app,config={'CACHE_TYPE': 'simple'}) db = database() #SEO @cache.cached(timeout=3600, key_prefix='cache_seo') def seo(): sql = """SELECT * FROM `v9_site`""" site = db.fetch_one(sql) return site #导航 @cache.cached(timeout=3600, key_prefix='cache_nav') def navigation(): sql = """SELECT * FROM `v9_category` WHERE 1 ORDER BY `listorder` ASC""" nav = db.fetch_all(sql) navlist = [] for val in nav: navlist.append({'catid':val[0], 'catname':val[9]}) return navlist #热门关键词 @cache.cached(timeout=3600, key_prefix='cache_hotkey') def hotkeywords(): sql = """SELECT * FROM `v9_keyword` WHERE 1 ORDER BY `videonum` DESC LIMIT 50""" hot = db.fetch_all(sql) return hot #本类推荐 @cache.memoize(timeout=3600) def localRec(catid): sql = """SELECT * FROM `v9_picture` WHERE `posids`=1 AND `catid`=%d ORDER BY `id` DESC LIMIT 10""" % catid result = db.fetch_all(sql) return result
然后跑起来,竟然报错了,我们看看错误代码
Traceback (most recent call last): File "app.py", line 5, in <module> from wap.views import wap File "./wap/views.py", line 18, in <module> cache = Cache(app,config={'CACHE_TYPE': 'simple'}) File "/usr/local/python3/lib/python3.7/site-packages/flask_cache/__init__.py", line 121, in __init__ self.init_app(app, config) File "/usr/local/python3/lib/python3.7/site-packages/flask_cache/__init__.py", line 156, in init_app from .jinja2ext import CacheExtension, JINJA_CACHE_ATTR_NAME File "/usr/local/python3/lib/python3.7/site-packages/flask_cache/jinja2ext.py", line 33, in <module> from flask.ext.cache import make_template_fragment_key ModuleNotFoundError: No module named 'flask.ext'
然后查找资料解决,打开/usr/local/python3/lib/python3.7/site-packages/flask_cache/jinja2ext.py,然后转到33行
#from flask.ext.cache import make_template_fragment_key from flask_cache import make_template_fragment_key
注释一行,增加一行OK了,原因是flask在python3.5以上导入模块的方式变了,按上述修改即可
最后再说下删除缓存的方法
#删除cache_seo缓存项 cache.delete('cache_seo') #同时删除cache_nav和cache_hotkey两个缓存项 cache.delete_many('cache_nav', 'cache_hotkey') #这里是删除缓存的localRec函数且参数为5的缓存项 cache.delete_memoized('localRec', 5) # 清理所有缓存 cache.clear()