为了尽量减少缓存穿透,并同时减少web的响应时间,可以针对那些需要一定时间才能获取结果的函数和那些不需要频繁更新的视图函数提供缓存服务,可以在一定的时间内直接返回结果而不是每次都需要计算或者从数据库中查找。flask_caching插件就是提供这种功能的神器。
pip install flask_caching
flask-caching内置的缓存类型CACHE_TYPE有:NullCache、SimpleCache、FileSystemCache、RedisCache、RedisSentinelCache、RedisClusterCache、UWSGICache、MemcachedCache、SASLMemcachedCache和SpreadSASLMemcachedCache(在Flask-Caching2.0中删除)。
NullCache:无缓存,其配置参数可以有:
SimpleCache:使用本地python字典进行存储,非线程安全,其配置参数可以有:
FileSystemCache:使用文件系统来存储缓存的值,其配置参数可以有:
RedisCache:使用Redis作为缓存后端,其配置参数可以有:
RedisSentinelCache:使用Redis哨兵模型缓存,其配置参数可以有:
RedisClusterCache:使用Redis自动分区缓存,其配置参数可以有:
MemcachedCache:使用memcached服务器作为缓存后端,支持pylibmc或memcache或Google应用程序引擎memcache库,其配置参数可以有:
SASLMemcachedCache:启用SASL的memcached服务器作为缓存后端,其配置参数可以有:
UWSGICache:使用uwsgi服务器作为缓存,其配置参数可以有:
注意:该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为超时时间;
可选参数有:
- #装饰器,装饰有参数函数,缓存该函数
- @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