Flask-caching 是flask 的一款缓存插件,它是从Flask-cache fork而来,一直在更新,而Flask-cache则已经很多年没有更新过了,如果想在flask项目里使用缓存,一定要使用Flask-caching, 安装方式如下
pip install -U flask-caching
官方文档地址: https://flask-caching.readthedocs.io/en/latest/
import time
from flask import Flask
from flask_caching import Cache
app = Flask(__name__)
cache_config = {
"CACHE_TYPE": "SimpleCache", # 缓存类型
"CACHE_DEFAULT_TIMEOUT": 300 # 默认缓存过期时间
}
app.config.from_mapping(cache_config)
cache = Cache(app)
CACHE_TYPE 我使用的是SimpleCache, 这将使用本地python目录做缓存,在flask-caching 2.0 中将被移除。
@app.route("/top_score/<int:id>")
@cache.cached(timeout=10)
def top_score(id):
return {'id': id, 'score': int(time.time())}
if __name__ == '__main__':
app.run(port=5555, debug=True)
从第一次请求的时间算起,10秒钟内,再次发起的请求将使用上一次缓存的结果。缓存的key 是请求的path路径,因此,id不同,得到的结果也就不同,但相同的id,10秒钟内得到的都是缓存的结果
对视图进行缓存时,一定要放在@app.route装饰器的前面。
flask-caching 也可以用来缓存普通的函数
@cache.cached(timeout=10)
def get_top_score(id):
return {'id': id, 'score': int(time.time())}
@app.route("/top_score/<int:id>")
def top_score(id):
return get_top_score(id)
虽然cache.cached 装饰的是get_top_score函数,但是,缓存的key依然是基于请求的path生成的,因此不同的id有不同的缓存。
但这仅限于你不指定key_prefix的情况,key_prefix参数值默认是 view/%s , 在底层处理时,flask-caching会找到本次请求的path 填充%s 的部分,但如果你指定了key_prefix 且不包含/%s ,那么就将基于被装饰的函数名称生成缓存的key
@cache.cached(timeout=10, key_prefix='top_score')
def get_top_score(id):
return {'id': id, 'score': int(time.time())}
@app.route("/top_score/<int:id>")
def top_score(id):
return get_top_score(id)
现在访问http://127.0.0.1:5555/top_score/4,然后访问http://127.0.0.1:5555/top_score/1, 将得到相同的内容。
在第3小结中,如果指定了key_prefix参数,那么缓存无法根据参数分别进行缓存,缓存的key里不包含实际传入的参数,这种情况下,可以使用memoize装饰器
@cache.memoize(timeout=10)
def get_top_score(id):
return {'id': id, 'score': int(time.time())}
使用memoize装饰器,它会默认将被装饰函数的参数加入到缓存的key中,这样,参数不同,其缓存结果也会不同。
import time
from flask import Flask
from flask_caching import Cache
app = Flask(__name__)
cache_config = {
"CACHE_TYPE": "FileSystemCache", # 缓存类型
"CACHE_DIR": "./cache"
}
app.config.from_mapping(cache_config)
cache = Cache(app)
@cache.memoize(timeout=10)
def get_top_score(id):
return {'id': id, 'score': int(time.time())}
@app.route("/top_score/<int:id>")
def top_score(id):
return get_top_score(id)
if __name__ == '__main__':
app.run(port=5555)
指定CACHE_TYPE 为 FileSystemCache, 并通过CACHE_DIR 设置缓存文件的存储位置,就可以在文件里缓存数据,相比于SimpleCache, 它的优势在于服务重启以后,缓存的数据仍然存在,但这样也只是适用于单点系统,如果服务是多点部署,就需要一个多点都能访问的存储介质,flask-caching也支持redis.
import time
from flask import Flask
from flask_caching import Cache
app = Flask(__name__)
cache_config = {
"CACHE_TYPE": "RedisCache", # 缓存类型
"CACHE_REDIS_URL": "redis://:123456@localhost:6379/2"
}
app.config.from_mapping(cache_config)
cache = Cache(app)
@cache.memoize(timeout=10)
def get_top_score(id):
return {'id': id, 'score': int(time.time())}
@app.route("/top_score/<int:id>")
def top_score(id):
return get_top_score(id)
if __name__ == '__main__':
app.run(port=5555)
redis是专门用来做缓存的,flask-caching 使用redis来做缓存介质相比于其他方案更快更稳定,因此推荐你使用这种方法。
如果你有额外的想要缓存的数据,而不是缓存函数的返回结果,可以直接使用cache对象的set方法和get方法分别进行缓存和读取缓存的操作。
import time,json
from flask import Flask
from flask_caching import Cache
app = Flask(__name__)
cache_config = {
"CACHE_TYPE": "RedisCache", # 缓存类型
"CACHE_REDIS_URL": "redis://:123456@localhost:6379/2"
}
app.config.from_mapping(cache_config)
cache = Cache(app)
def get_top_score(id):
return {'id': id, 'score': int(time.time())}
@app.route("/top_score/<int:id>")
def top_score(id):
key = str(id)
score = cache.get(key) # 先从缓存中获取
print(score)
if score is None: # 没有缓存,调用get_top_score 函数获取
score = get_top_score(id)
cache.set(key, score, timeout=10) # 过期时间设置为10秒
return score
if __name__ == '__main__':
app.run(port=5555)
flask-caching 提供了清除缓存的办法,在app被创建且完成cache初始化以后,可以在不运行flask服务的条件下清除缓存
if __name__ == '__main__':
with app.app_context():
cache.clear()
QQ交流群: 211426309