启掘金成长之旅!这是我参与「掘金日新计划 · 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直接去设置缓存,但是可能需要考虑的就比较多了。