Flask 缓存

786 阅读4分钟

启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

从开始学习WEB框架到现在,除了数据库之外有很多临时的数据存储,比如:cookie、session、cache,那么今天来聊聊缓存吧。

缓存

介绍

常规的web请求逻辑是前端发起请求,后端接收请求,后端根据请求查询数据库,数据库对查询数据进行返回,但是当访问量大的时候,一些资源会被频繁的访问,比如首页的导航信息,比如logo这些内容其实变换的概率很小,但是每次请求都需要从新从数据库加载或者从新进行页面渲染,当然这样会对web服务器和数据库照成很大的压力。在这种情况下就衍生出了很多解决的方案,包括数据库集群,读写分离等等,但是最简单的一种思路就是:把经常出现在项目当中的内容单独存放在一个位置上,之后涉及到这个内容的查询不去查询数据库,而是直接从单独存放的位置取出来。这样减少了查询,也降低了服务器的压力,那么这种策略就是缓存(cache)。

容器

存储缓存的思路有很多种,比如:

使用文件存放缓存内容

文件作为缓存存储比较直观,但是很难灵活的处理存储的内容,

使用数据库存放缓存内容

数据库作为缓存存储查询的速度还是差强人意,毕竟缓存的东西99%是查询频繁的

使用内存存储缓存内容

使用内存作为缓存的存储,效率是不错的,但是注意的是内存的大小是有限的,如果缓存设置太多会出现崩溃线性,比如:缓存穿透、缓存雪崩、缓存击穿。

常被使用到的缓存技术有两种:

memcache

memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。

redis

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库。由于是基于内存存储的也是可以作为缓存的容器的,并且相较于memcache,redis 键值对的值可以存储多种类型,并且键本身具有的过期能力在做缓存的时候更加方便灵活。

flask缓存

flask本身提供了cache插件,flask-cache,开发者可以基于flask-cache进行缓存设置:

flask-cache配置

flask-cache 可以支持多种类型的缓存,通过CACHE_TYPE来配置具体的缓存类型

默认无缓存

CACHE_TYPE = null # 缓存类型,默认的缓存类型,无缓存
CACHE_TYPE = 'simple' # 使用本地python字典进行存储,线程非安全

文件缓存

CACHE_TYPE = 'filesystem' # 缓存类型,使用文件系统来存储缓存的值
CACHE_DIR = "" # 文件目录

memcache 缓存

CACHE_TYPE = 'memcached' # 缓存类型,使用memcached服务器缓存
CACHE_KEY_PREFIX # 设置cache_key的前缀
CAHCE_MEMCACHED_SERVERS    # 服务器地址的列表或元组
CACHE_MEMCACHED_USERNAME # 用户名
CACHE_MEMCACHED_PASSWORD # 密码

redis缓存

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_NO_NULL_WARNING = "warning" # null类型时的警告消息
CACHE_DEFAULT_TIMEOUT # 默认过期/超时时间,单位为秒
CACHE_THRESHOLD    # 缓存的最大条目数

使用流程:

from flask import Flask, request , render_template , redirectr
from flask_caching import Cache  
from models import User
​
app = Flask(__name__)
cache = Cache(app, config={'CACHE_TYPE': 'simple'})
​
@app.route("/login")  
def login():  
    if request.method == "POST":
        username = request.json.get("username")
        password = request.json.get("password")
        if username and password:
            user = User.query.filter_by(username = username,password = password).first()
            if user:
                cache.set("user_id", user.id) #设置缓存
                cache.set("usename", user.usename) #设置缓存
                return redirectr("/index")
    return render_template("login.html")     
​
@app.route("/index")                 
def index():
    user_id = cache.get("user_id") #获取缓存
    usename = cache.get("usename") #获取缓存
    if user_id and username:
        result = {"user_id": user_id,"username": username}
    else:
        user_id = request.cookies.get("user_id")
        user = User.query.get(user_id)
        ache.set("user_id", user.id) #设置缓存
        cache.set("usename", user.usename) #设置缓存
        result = {"user_id": user_id,"username": user.usename}
    return render_template("login.html",**result)
​
@app.router("/logout")
def logout():
     user_id = request.cookies.get("user_id")
     response = redirectr("/login")
     response.delete_cookie("user_id")
     cache.clear() #清楚缓存
     return response
​
if __name__ == '__main__':
   app.run(host='0.0.0.0')

这里也保护了一个缓存的逻辑,就是查询缓存,如果缓存有就使用缓存,如果缓存没有就放到缓存当中。

基于flask的缓存就聊这么多,当然也可以使用redis直接去设置缓存,但是可能需要考虑的就比较多了。