
前言
为什么要引入缓存,缓存在一些高并发的系统的重要性是不言而喻。一般我们的web服务的流程是:
客户端请求我们的服务端 经过我们的nginx分发请求到后端serve serve访问我们的数据库存取我们的数据(可能还需要访问第三方的请求接口) 返回我们的处理号的数据给客户端
在访问到我们的后端的serve的时候相关的数据库访问之类的都是需要产生IO操作的,IO操作引起的性能的消耗是比较高的,特别是磁盘IO的操作;想提高系统的性能,我们就需要尽量减少IO的操作,而引入缓存可以有效的避免这种情况;减少和我们的数据库进行交互,可以有效减少相关的IO,降低数据库的负载,同时减少web的响应时间
redis是一个内存的数据库,而flask_caching插件就是可以结合redis提供这种相关缓存功能。
1. 安装插件
安装Flask-Caching
或pip安装
pip install Flask-Caching
2. 创建对象

一些常用配置参数详解:
# CACHE_KEY_PREFIX = 'fastapi::'
# CACHE_TYPE = 'redis'
# CACHE_REDIS_URL = 'redis://localhost:16379/0'
# CACHE_DEFAULT_TIMEOUT = 60 * 60
# 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
# cache.init_app(app, config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_HOST': '127.0.0.1',
# 'CACHE_REDIS_PASSWORD': '', 'CACHE_REDIS_PORT': '6379', 'CACHE_REDIS_DB': 2})
# cache.init_app(app, config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_HOST': 'r-wz9bc5b455d2fc04.redis.rds.aliyuncs.com', 'CACHE_REDIS_PASSWORD': 'CVPW89fpvcRVFPPFJ4e5bvgksrtbgs', 'CACHE_REDIS_PORT': '6379', 'CACHE_REDIS_DB': 14})
创建单例对象,默认配置使用redis做缓存初始化配置:
from loguru import logger
from flask_caching import Cache
# 创建缓存的实例
cache = Cache()
def register_init_cache(app, cache_config={'CACHE_TYPE': 'redis', 'CACHE_REDIS_HOST': '127.0.0.1', 'CACHE_REDIS_PASSWORD': '', 'CACHE_REDIS_PORT': '6379', 'CACHE_REDIS_DB': 2, 'CACHE_KEY_PREFIX ': ''}):
cache.init_app(app, config=cache_config)
logger.info('初始化flask_caching成功')
3. 开始使用缓存
if __name__ == '__main__':
app = create_app()
# 初始化缓存
from common.ext.flaskcaching import cache,register_init_cache
register_init_cache(app)
# 测试缓存
@app.route('/cace')
@cache.cached(timeout=30) # 专门为装饰视图函数准备的装饰器
def test2():
print("我是没有缓存进来的数据")
return 'ok'
# run_task_fib(20)
print(app.url_map)
app.run(host='127.0.0.1', port='8808', debug=True,threaded=False)
启动服务访问接口测试:http://127.0.0.1:8808/cace
第一次访问:
* Running on http://127.0.0.1:8808/ (Press CTRL+C to quit)
2021-03-01 16:27:04.675 | INFO | common.ext.trace_logger:trace_add_log_record:50 - {"traceid": "97a084514c4a42768af8f1552378e55e", "trace_index": 1, "event_des": "请求开始", "msg_dict": {"headers": {"X-Access-Token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ4aWFvemhvbmd0b25neHVlIiwiZXhwIjoxNjE0NDExMTE4LCJpYXQiOjE2MTQyMzgzMTgsImF1ZCI6Ind3dy54aWFvemhvbmcuY29tIiwic3ViIjoienl4Iiwic2NvcGVzIjpbIm9wZW4iXSwiZGF0YSI6eyJ1c2VybmFtZSI6InhpYW96aG9uZyIsInVzZXJpZCI6IjEifX0.lDSBGm6houMka35uS_JFBbQYs1EYn4EpBjygfUS0cLU", "User-Agent": "PostmanRuntime/7.26.8", "Accept": "*/*", "Cache-Control": "no-cache", "Postman-Token": "69dfed49-d955-4868-8946-635189df121e", "Host": "127.0.0.1:8808", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"}, "url": "http://127.0.0.1:8808/cace", "method": "GET", "ip": "127.0.0.1", "params": {"args": "", "form": "", "json": ""}, "start_time": "2021-03-01 16:27:04.673180"}}
MiddlewareTraceLogger-----before_request
2021-03-01 16:27:04.678 | 我是没有缓存进来的数据
INFO MiddlewareTraceLogger-----after_request=
| sssssssssss 200 OK
common.ext.trace_logger:trace_add_log_record:50 - {"traceid": "97a084514c4a42768af8f1552378e55e", "trace_index": 2, "event_des": "请求结束", "msg_dict": {"cost_time": "5.0ms", "rsp_data": "ok"}}
127.0.0.1 - - [01/Mar/2021 16:27:04] "GET /cace HTTP/1.1" 200 -
MiddlewareTraceLogger-----before_request
第二次访问:
2021-03-01 16:27:08.386 | MiddlewareTraceLogger-----after_request=
INFO sssssssssss 200 OK
| common.ext.trace_logger:trace_add_log_record:50 - {"traceid": "e58c4edd3f324903a6254ee9caf0e373", "trace_index": 1, "event_des": "请求开始", "msg_dict": {"headers": {"X-Access-Token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ4aWFvemhvbmd0b25neHVlIiwiZXhwIjoxNjE0NDExMTE4LCJpYXQiOjE2MTQyMzgzMTgsImF1ZCI6Ind3dy54aWFvemhvbmcuY29tIiwic3ViIjoienl4Iiwic2NvcGVzIjpbIm9wZW4iXSwiZGF0YSI6eyJ1c2VybmFtZSI6InhpYW96aG9uZyIsInVzZXJpZCI6IjEifX0.lDSBGm6houMka35uS_JFBbQYs1EYn4EpBjygfUS0cLU", "User-Agent": "PostmanRuntime/7.26.8", "Accept": "*/*", "Cache-Control": "no-cache", "Postman-Token": "08a2ded6-8da9-4b4b-9faa-9d3ea145f109", "Host": "127.0.0.1:8808", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"}, "url": "http://127.0.0.1:8808/cace", "method": "GET", "ip": "127.0.0.1", "params": {"args": "", "form": "", "json": ""}, "start_time": "2021-03-01 16:27:08.386660"}}
2021-03-01 16:27:08.387 | INFO | common.ext.trace_logger:trace_add_log_record:50 - {"traceid": "e58c4edd3f324903a6254ee9caf0e373", "trace_index": 2, "event_des": "请求结束", "msg_dict": {"cost_time": "5.0ms", "rsp_data": "ok"}}
127.0.0.1 - - [01/Mar/2021 16:27:08] "GET /cace HTTP/1.1" 200 -
区别:第一次访问进入到函数内部执行了 print("我是没有缓存进来的数据")
第二次访问直接的返回网络的OK 没有进入内部进行执行。
查看问的本地的redis客户端:redis配置信息为:
cache_config ={'CACHE_TYPE': 'redis', 'CACHE_REDIS_HOST': '127.0.0.1', 'CACHE_REDIS_PASSWORD': '', 'CACHE_REDIS_PORT': '6379', 'CACHE_REDIS_DB': 2,'CACHE_KEY_PREFIX ':''}):
ps:# CACHE_KEY_PREFIX # 设置cache_key的前缀 查看db2的数据:

flask_caching 其他测试:
键值对设置测试
相关参数介绍
# 标准接口
clear():清除缓存
get(key):获取一个键的值,如果值是json格式会自动转化成字典
set(key,value,timeout):设置一个键值,value可以是字典,会自动转化json格式的字符串
set_many(key,value,timeout):设置多个键值对
add(key, value, timeout=None):设置一个键值,如果存在就pass,注意和set的区别
delete(key):删除键
delete_many(k1,k2...):删除多个键值
get_many(k1,k2...):获取多个键的值
get_dict(k1,k2...):获取多个键的值,返回一个字典
has(k):查询是否存在一个键
inc(self, key, delta=1):将键的值加一
dec(self, key, delta=1):将键的值减一
具体示例代码:
if __name__ == '__main__':
app = create_app()
# 初始化缓存
from common.ext.flaskcaching import cache,register_init_cache
register_init_cache(app)
@app.route('/caceshezhi')
def test():
# 设置timeout过期时间
cache.set('name', 'xiaozhong', timeout=30)
cache.set('age','21', timeout=30)
cache.set('renwu', {'name': 'aaa', 'age': 20})
name = cache.get('name')
age = cache.get('age')
print('设置name后查询获取',name)
print('设置age后查询获取', age)
cache.set_many([('xiaozhong1', 'hhh'), ('xiaozhong2', 'jjj')])
print(cache.get_many("xiaozhong1", "xiaozhong2"))
print(cache.delete("name"))
print(cache.delete_many("xiaozhong1", "xiaozhong2"))
print("删除后在获取信息")
x = cache.get('name')
print(x)
print(cache.get_many("xiaozhong1", "xiaozhong2"))
return '缓存设置和删除'
# run_task_fib(20)
print(app.url_map)
app.run(host='127.0.0.1', port='8808', debug=True,threaded=False)
启动服务测试:http://127.0.0.1:8808/caceshezhi
MiddlewareTraceLogger-----before_request
设置name后查询获取 xiaozhong
设置age后查询获取 21
['hhh', 'jjj']
1
2
删除后在获取信息
None
[None, None]
MiddlewareTraceLogger-----after_request=
sssssssssss 200 OK
参考资料:
[1] https://www.cnblogs.com/cwp-bg/p/9687005.html
End
纯属个人实践中相关经验之谈,如有纰漏,还希望大佬们多多提点!
小钟同学 | 文 【原创】| QQ:308711822
文章转载自小儿来一壶枸杞酒泡茶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




