暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Flask + Ant Vue 实战 (17)-插件库flask_caching-处理缓存

小儿来一壶枸杞酒泡茶 2021-03-01
573

前言

为什么要引入缓存,缓存在一些高并发的系统的重要性是不言而喻。一般我们的web服务的流程是:

  1. 客户端请求我们的服务端
  2. 经过我们的nginx分发请求到后端serve
  3. serve访问我们的数据库存取我们的数据(可能还需要访问第三方的请求接口)
  4. 返回我们的处理号的数据给客户端

在访问到我们的后端的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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论