1.介绍
缓存介绍
如果您的应用运行很慢,那就尝试引入一些缓存吧。好吧,至少这是提高表现最简单的方法。缓存的工作是什么呢?比如说您有一个需要一段时间才能完成的函数,但是这个函数的返回结果可能在5分钟之内都是足够有效的,因此您可以将这个结果放到缓存中一段时间,而不用反复计算。
如果同一个请求会被多次调用,每次调用都会消耗很多资源,并且每次返回的内容都相同,就该使用缓存了Flask 本身并不提供缓存功能,但是作为Flask 基础的 Werkzeug 库,则提供了一些基础的缓存支持。
Werkzeug 支持多种缓存后端,通常的选择是 Memcached 服务器。
缓存类型
我们来了解一下flask-caching支持的缓存类型:
flask-caching内置的缓存类型CACHE_TYPE有:NullCache、SimpleCache、FileSystemCache、RedisCache、RedisSentinelCache、RedisClusterCache、UWSGICache、MemcachedCache、SASLMemcachedCache和SpreadSASLMemcachedCache(在Flask-Caching2.0中删除)。
其中:
NullCache:无缓存,其配置参数可以有:
- CACHE_NO_NULL_WARNING:不会抛出警告信息;
- CACHE_DEFAULT_TIMEOUT:如果未指定超时,则使用默认超时,时间单位是秒。
SimpleCache:使用本地python字典进行存储,非线程安全,其配置参数可以有:
- CACHE_DEFAULT_TIMEOUT:如果未指定超时,则使用默认超时,时间单位是秒;
- CACHE_THRESHOLD:最大缓存数;
- CACHE_IGNORE_ERRORS:其值为True时,在删除过程中发生的任何错误将被忽略;其值为False时,在删除过程中第一个错误时停止删除;
FileSystemCache:使用文件系统来存储缓存的值,其配置参数可以有:
- CACHE_DEFAULT_TIMEOUT:如果未指定超时,则使用默认超时,时间单位是秒;
- CACHE_IGNORE_ERRORS:其值为True时,在删除过程中发生的任何错误将被忽略;其值为False时,在删除过程中第一个错误时停止删除;
- CACHE_DIR:存储缓存的目录;
- CACHE_THRESHOLD:最大缓存数;
- CACHE_OPTIONS:在缓存类实例化期间传递的可选字典。
RedisCache:使用Redis作为缓存后端,其配置参数可以有:
- CACHE_DEFAULT_TIMEOUT:如果未指定超时,则使用默认超时,时间单位是秒;
- CACHE_KEY_PREFIX:所有它都可以用于应用程序的应用程序使用相同的键;
- CACHE_OPTIONS:在缓存类实例化期间传递的可选字典;
- CACHE_REDIS_HOST:Redis 服务器主机;
- CACHE_REDIS_PORT:Redis 服务器端口,默认为 6379;
- CACHE_REDIS_PASSWORD:服务器的 Redis 密码;
- CACHE_REDIS_DB :Redis db(从零开始的数字索引),默认为 0;
- CACHE_REDIS_URL:| 连接到 Redis 服务器的 URL,例子redis://user:password@localhost:6379/2 。
RedisSentinelCache:使用Redis哨兵模型缓存,其配置参数可以有:
- CACHE_KEY_PREFIX:所有它都可以用于应用程序的应用程序使用相同的键;
- CACHE_REDIS_SENTINELS:Redis哨兵地址的列表或元组;
- CACHE_REDIS_SENTINEL_MASTER:哨兵配置中的主服务器的名称
- CACHE_REDIS_PASSWORD:服务器的 Redis 密码;
- CACHE_REDIS_DB:Redis db(从零开始的数字索引),默认为 0。
RedisClusterCache:使用Redis自动分区缓存,其配置参数可以有:
- CACHE_KEY_PREFIX:所有它都可以用于应用程序的应用程序使用相同的键;
- CACHE_REDIS_CLUSTER:一串以逗号分隔的 Redis 集群节点地址;
- CACHE_REDIS_PASSWORD:服务器的 Redis 密码。
MemcachedCache:使用memcached服务器作为缓存后端,支持pylibmc或memcache或Google应用程序引擎memcache库,其配置参数可以有:
- CACHE_DEFAULT_TIMEOUT:如果未指定超时,则使用默认超时,时间单位是秒;
- CACHE_KEY_PREFIX:所有它都可以用于应用程序的应用程序使用相同的键;
- CACHE_MEMCACHED_SERVERS:服务器地址的列表或元组。
注意:Flask-Caching不会将额外的配置选项传递给memcached后端,要向这些缓存添加其他配置。
SASLMemcachedCache:启用SASL的memcached服务器作为缓存后端,其配置参数可以有:
- CACHE_DEFAULT_TIMEOUT:如果未指定超时,则使用默认超时,时间单位是秒;
- CACHE_KEY_PREFIX:所有它都可以用于应用程序的应用程序使用相同的键;
- CACHE_OPTIONS:在缓存类实例化期间传递的可选字典;
- CACHE_MEMCACHED_SERVERS:服务器地址的列表或元组;
- CACHE_MEMCACHED_USERNAME:使用memcached进行SASL身份验证的用户名;
- CACHE_MEMCACHED_PASSWORD:使用memcached进行SASL身份验证的密码。
UWSGICache:使用uwsgi服务器作为缓存,其配置参数可以有:
- CACHE_UWSGI_NAME:要连接的uwsgi缓存实例的名称,例如:mycache @ localhost :3031,默认为空字符串;
注意:该UWSGICache没有维护也没有测试,不建议使用。
2.安装模块
pip3 install redis -i https://pypi.douban.com/simple
pip3 install flask-caching -i https://pypi.douban.com/simple
3.创建一个Flask-Cache的实例
3.1介绍
有很多种实例方式,这里介绍我最常用的一种
3.2 第一种使用
view(推荐)
from flask import Flask
from flask_cache import Cache
config={
'CACHE_TYPE': 'redis', # Use Redis
'CACHE_REDIS_HOST': 'abc.com', # Host, default 'localhost'
'CACHE_REDIS_PORT': 6379, # Port, default 6379
'CACHE_REDIS_PASSWORD': '111', # Password
'CACHE_REDIS_DB': 2
}
app = Flask(__name__)
# 实例
cache = Cache(config=config)
# 绑定到app上
cache.init_app(app)
3.3 其他种使用
from flask import Flask
from flask_caching import Cache
#配置RedisCache缓存类型参数值,我们使用本地的redis,没有密码
config={
'CACHE_TYPE':'redis', #使用redis作为缓存
'CACHE_REDIS_HOST':'127.0.0.1', #redis地址
'CACHE_REDIS_PORT':6379 #redis端口号
}
app = Flask(__name__)
#初始化缓存
cache=Cache(app=app,config=config) #创建Cache对象
#或使用init_app()初始化缓存
#cache=Cache() #创建Cache对象
#cache.init_app(app=app,config=config)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
3.3 介绍参数
CACHE_TYPE:设置缓存的类型
# 下面五个参数是所有的类型共有的
CACHE_NO_NULL_WARNING = "warning" # null类型时的警告消息
CACHE_ARGS = [] # 在缓存类实例化过程中解包和传递的可选列表,用来配置相关后端的额外的参数
CACHE_OPTIONS = {} # 可选字典,在缓存类实例化期间传递,也是用来配置相关后端的额外的键值对参数
CACHE_DEFAULT_TIMEOUT # 默认过期/超时时间,单位为秒
CACHE_THRESHOLD # 缓存的最大条目数
CACHE_TYPE = null # 默认的缓存类型,无缓存
CACHE_TYPE = 'simple' # 使用本地python字典进行存储,线程非安全
CACHE_TYPE = 'filesystem' # 使用文件系统来存储缓存的值
CACHE_DIR = "" # 文件目录
CACHE_TYPE = 'memcached' # 使用memcached服务器缓存
CACHE_KEY_PREFIX # 设置cache_key的前缀
CAHCE_MEMCACHED_SERVERS # 服务器地址的列表或元组
CACHE_MEMCACHED_USERNAME # 用户名
CACHE_MEMCACHED_PASSWORD # 密码
CACHE_TYPE = 'uwsgi' # 使用uwsgi服务器作为缓存
CACHE_UWSGI_NAME # 要连接的uwsgi缓存实例的名称
CACHE_TYPE = 'redis' # 使用redis作为缓存
CACHE_KEY_PREFIX # 设置cache_key的前缀
CACHE_REDIS_HOST # redis地址
CACHE_REDIS_PORT # redis端口
CACHE_REDIS_PASSWORD # redis密码
CACHE_REDIS_DB # 使用哪个数据库
# 也可以一键配置
CACHE_REDIS_URL 连接到Redis服务器的URL。示例redis://user:password@localhost:6379/2
3.5 配置多个缓存实例
cache1 = Cache()
cache2 = Cache()
cache1.init_app(app, config={ 'CACHE_TYPE' : 'redis','CACHE_REDIS_HOST':'192.168.1.20',
'CACHE_REDIS_PORT':'6390'})
cache2.init_app(app, config={ 'CACHE_TYPE' : 'redis','CACHE_REDIS_HOST':'192.168.1.21',
'CACHE_REDIS_PORT':'6390'})
4.使用
装饰器,装饰无参数函数,缓存该函数
使用格式
@cache.cached(timeout=None,key_prefix=None,unless=None,forced_update=None,query_string=False)
参数介绍
- timeout为超时时间,默认为None,即永不过期
- key_prefix:缓存指定的函数;缓存项键值的前缀,默认为”view/%s”
- unless:是否启用缓存,如果为True,不启用缓存;默认为None,即缓存有效
- forced_update:缓存是否实时更新,如果为True,无论是否过期都将更新缓存;
- query_string:为True时,缓存键是先将参数排序然后哈希的结果。
实例
@app.route('/test2')
@cache.cached(timeout=30) # 专门为装饰视图函数准备的装饰器
def test2():
print('111')
return 'ok'
装饰器,装饰有参数函数,缓存该函数
使用格式
@cache.memoize(timeout=None,make_name=None,unless=None,forced_update=None,query_string=False)
参数介绍
与cache.cached()方法类似,区别为cache.memoize有make_name,其作用是设置函数的标志,如果没有就使用装饰的函数。
Flask-Cache还提供了另一个装饰器方法”cache.memoize()”,它与”cache.cached()”的区别就是它会将函数的参数也放在缓存项的键值中:
我们再次访问”/list”地址,对于不同的参数,”method called”会一直在控制台上打印出,而对于相同的参数,第二次就不会打印了。
所以对于带参数的函数,你要使用”cache.memoize()”装饰器,而对于不带参数的函数,它同”cache.cached()”基本上一样。
”cache.memoize()”装饰器也有三个参数,
”timeout”和”unless”参数同”cache.cached()”一样,
就是第二个参数”make_name”比较特别,它是一个回调函数,传入的是被装饰的函数名,返回是一个字符
实例
@cache.memoize(timeout=50)
def create_list(num):
print 'method create_list called'
l = []
for i in range(num):
l.append(str(i))
return l
@app.route('/list/<int:num>')
def list(num):
return ', '.join(create_list(num))
cache.cached用来装饰普通函数
参数:
key_prefix:设置函数的标志,如果没有就使用装饰的函数 # 其他参数同cached
我们访问”/list”地址时,第一次控制台上会有”method called”输出,第二次就不会了,说明缓存起效了。
装饰普通函数时必须指定明确的”key_prefix”参数,因为它不像视图函数,可以使用请求路径”request.path”作为缓存项的键值。
如果函数带参数,对于不同的参数调用,都会使用同一缓存项,即返回结果一样。
@cache.cached(timeout=50, key_prefix='get_list')
def get_list():
print 'method get_list called'
return ['a','b','c','d','e']
@app.route('/list')
def list():
return ', '. join(get_list())
@cache.memoize用来装饰普通函数
参数
参数:
make_name:设置函数的标志,如果没有就使用装饰的函数 # 其他参数同cached
我们访问”/list”地址时,第一次控制台上会有”method called”输出,第二次就不会了,说明缓存起效了。
装饰普通函数时必须指定明确的”make_name”参数,因为它不像视图函数,可以使用请求路径”request.path”作为缓存项的键值。
如果函数带参数,对于不同的参数调用,都会使用同一缓存项,即返回结果一样。
实例
# 装饰有参的函数
@cache.memoize(timeout=60, make_name='get_result')
def get_result(n):
return str(n)
@cache.cached(timeout=30)
def test_xxx():
return 'this is a test'
缓存键值对
实例一
# __init__.py
from flask import Flask, current_app, make_response, request
from test import get_result, test_xxx
from exsentions import cache
app = Flask(__name__)
app.config['SECRET_KEY'] = '123'
cache.init_app(app, config={ 'CACHE_TYPE' : 'redis','CACHE_REDIS_HOST':'192.168.1.20',
'CACHE_REDIS_PORT':'6390'})
@app.route('/test1')
def test():
cache.set('name','xiaoming', timeout=30)
cache.set('person',{'name':'aaa', 'age':20})
x = cache.get('name')
print(x)
cache.set_many([('name1','hhh'),('name2','jjj')])
print(cache.get_many("name1","name2"))
print(cache.delete("name"))
print(cache.delete_many("name1","name2"))
return res
if __name__ == '__main__':
app.run(host='127.0.0.1', port=80, debug=True)
实例二
#设置
cache.set(key,value,timeout=None) #设置一个缓存对象
cache.set_many([(key,value),(key,value),...,(key,value)],timeout=None) #设置多个缓存对象
#获取
cache.get(key) #获取一个缓存对象
cache.get_many(key1,key2,....) #获取多个缓存对象
#删除
cache.get.delete(key) #删除一个缓存对象
cache_delete_many(key1,key2,...) #删除多个缓存对象
cache.clear() #删除所有缓存对象
删除缓存
对于普通缓存,你可以使用”delete()”方法来删除缓存项,而对于”memoize”缓存,你需要使用”delete_memoized”方法。如果想清除所有缓存,可以使用”clear()”方法。
cache.delete('get_list') # 删除'get_list'缓存项
cache.delete_many('get_list', 'view_hello') # 同时删除'get_list'和'view_hello'缓存项
cache.delete_memoized('create_list', 5) # 删除调用'create_list'函数并且参数为5的缓存项
cache.clear() # 清理所有缓存
Jinja2模板中使用缓存
其实在Jinja2模板中,我们还可以使用”{% cache %}”语句来缓存模板代码块:
这样”{% cache %}”和”{% endcache %}”语句中所包括的内容就会被缓存起来。”{% cache %}”语句的第一个参数是”timeout”过期时间,默认为永不过期;第二个参数指定了缓存项的键值,如果不设,键值就是”模板文件路径”+”缓存块的第一行”。
{% cache 50, 'temp' %}
<p>This is under cache</p>
{% endcache %}
然后在代码中,我们可以这样获取缓存项实际的键值:
打印出来看看,你会发现实际的键值其实是”_template_fragment_cache_temp”。如果你要删除该缓存项,记得要传入实际的键值,而不是模板上定义的’temp’。
from flask_cache import make_template_fragment_key
key = make_template_fragment_key('temp')
本文参考
(253条消息) Flask-Cache——缓存_qq_41134008的博客-CSDN博客https://blog.csdn.net/qq_41134008/article/details/105698861flask插件系列之flask_caching缓存 - 倥偬时光 - 博客园 (cnblogs.com)https://www.cnblogs.com/cwp-bg/p/9687005.html(253条消息) flask缓存机制_冰_戒的博客-CSDN博客_flask缓存机制https://blog.csdn.net/huang_yong_peng/article/details/82622077
Flask框架——flask-caching缓存 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/544198743
版权归原作者 骑台风走 所有, 如有侵权,请联系我们删除。