为了尽量减少缓存穿透,并同时减少web的响应时间,可以针对那些需要一定时间才能获取结果的函数和那些不需要频繁更新的视图函数提供缓存服务,可以在一定的时间内直接返回结果而不是每次都需要计算或者从数据库中查找。flask_caching插件就是提供这种功能的神器。
安装flask_caching库:
pip install 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没有维护也没有测试,不建议使用。
配置参数
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
初始化
以缓存类型为RedisCache为例:
from flask import Flask
from flask_caching import Cache
import time
# 配置RedisCache缓存类型参数值,使用本地的redis,没有密码
config = {
'CACHE_TYPE': 'redis', # 使用redis作为缓存
'CACHE_REDIS_HOST': '127.0.0.1', # redis地址
'CACHE_REDIS_PORT': 6379 # redis端口号
}
# simple
# cache = Cache(app, config={'CACHE_TYPE': 'simple'})
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 index():
return 'hello world!'
if __name__ == '__main__':
app.run()
Cache对象的主要方法有:
#装饰器,装饰无参数函数,缓存该函数
@cache.cached(timeout=None, key_prefix=None, unless=None, forced_update=None, query_string=False)
其中:timeout为超时时间;
可选参数有:
- key_prefix:缓存指定的函数;
- unless:是否启用缓存,如果为True,不启用缓存;
- forced_update:缓存是否实时更新,如果为True,无论是否过期都将更新缓存;
- query_string:为True时,缓存键是先将参数排序然后哈希的结果。
#装饰器,装饰有参数函数,缓存该函数
@cache.memoize(timeout=None, make_name=None, unless=None, forced_update=None, query_string=False)
与cache.cached()方法类似,区别为cache.memoize有make_name,其作用是设置函数的标志,如果没有就使用装饰的函数。
使用缓存
为了能更好地体现效果,通过设置休眠时间来模拟数据加载时间。
示例代码:
from flask import Flask
from flask_caching import Cache
import time
# 配置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('/')
@cache.cached(timeout=200) # 设置超时时间
def index():
time.sleep(5)
return 'hello world!'
if __name__ == '__main__':
app.run()
在缓存对象中,我们可以使用以下代码来设置、获取、删除缓存对象:
# 设置
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() # 删除所有缓存对象
示例代码:
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 index():
cache.set('name', '王五', timeout=30) # 设置键为name,value为小明,超时时间为30秒的缓存对象
print(cache.get('name')) # 打印键为name的缓存对象值
cache.set_many({'name1': '李四', 'name2': '张三'}, timeout=30) # 设置多个缓存对象
print(cache.get_many("name1", "name2")) # 打印多个缓存对象值
print(cache.delete("name")) # 删除键为name的缓存对象
print(cache.delete_many("name1", "name2")) # 删除多个缓存对象
print(cache.get_many("name1", "name2")) # 打印多个缓存对象值
return '缓存对象'
if __name__ == '__main__':
app.run()
运行结果:
示例代码:
from flask import Flask, request
from flask_caching import Cache
app = Flask(__name__)
# simple使用字典存储
cache = Cache(app, config={'CACHE_TYPE': 'simple'})
@app.route('/')
@cache.cached(timeout=20)
def index():
print(request.path)
s = 'test cache'
cache.set('b', 123)
print('test cache')
return s
@app.route('/test')
def test():
print(cache.get('b'))
return 'ok'
if __name__ == '__main__':
app.run()
运行结果:
更多flask_caching用法详见官方网址:Flask-Caching — Flask-Caching 1.0.0 documentation
版权归原作者 IT之一小佬 所有, 如有侵权,请联系我们删除。