当一个借口是被频繁访问的,我要获取的数据不经常被变化。
如果每次访问都通过查询数据库,会导致速度变慢。
解决办法:引入缓存。在第一次查询出来后就找变量缓存出来。第二次被访问时,先去寻找变量中是否存在需要的数据,如果有,直接进行引用,如果没有,就重新发起请求。
我们通过redis数据库进行存储。
步骤:
- 先尝试从redis中获取数据
- 如果redis中有数据,则直接返回
- 如果没有数据,则去数据库中再进行查询。
- 将mysql中拿到的数据保存到redis中
- 将数据返回给前端。
案例:将城区信息展现给用户
from . import api
from ihome.models import Area
from ihome.utils.response_code import RET
from ihome.utils.image_storage_tencent import storage
from flask import g, current_app, jsonify, request, session
from ihome.utils.commons import login_required
from ihome import db, redis_store
from ihome.models import User
from ihome.contstants import TENCENT_URL_DOMAIN, AREA_INFO_REDIS_CACHE_EXPIRES
import json
@api.route("/areas")
def get_area_info():
"""获取城区信息"""
# 尝试从redis中读取数据
try:
resp_json = redis_store.get("area_info")
except Exception as e:
current_app.logger.error(e)
else:
if resp_json is not None:
# redis有缓存数据
current_app.logger.info("hit redis area_info")
return resp_json, 200, {"Content-Type": "application/json"}
# 查询数据库读取城区信息
try:
area_li = Area.query.all()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="数据库异常")
area_dict_li = []
# 将对象转换为字典
for area in area_li:
area_dict_li.append(area.to_dict())
# 将数据转换为json字符串
resp_dict = dict(errno=RET.OK, errmsg="OK", data=area_dict_li)
resp_json = json.dumps(resp_dict)
# 将数据保存到redis中
try:
redis_store.setex("area_info", AREA_INFO_REDIS_CACHE_EXPIRES, resp_json)
except Exception as e:
current_app.logger.error(e)
return resp_json, 200, {"Content-Type": "application/json"}
缓存数据同步的问题:
保证mysql与redis数据的一致相同问题
- 在操作mysql时进行redis修改。(万一忘了呢)
- 给redis缓存数据设置有效期,保证过了有效期缓存数据会被删除。