在最近的项目中,出于优化响应速度考虑,将项目中绝大部分数据都放到了缓存中,感觉django_redis的使用很方便,所以分享下。
首先,安装包
pip install django-redis
在settings中配置
CACHES = {
"intelligent": {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://xx.xxx.xxx.x:6379/3',
'TIMEOUT': 60 * 60 * 24,
'OPTIONS': {
'PASSWORD': 'XXXXX',
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 1000}
}
},
"resume": {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://xx.xxx.xxx.x:6379/3'',
'TIMEOUT': 60 * 60 * 24,
'OPTIONS': {
'PASSWORD': 'XXXXX',
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 1000}
}
},
}
在视图中使用
# 获取实体词接口
from django_redis import get_redis_connection
import random
class EntitiesWordView(APIView):
permission_classes = [IsAuthenticated, ]
def get(self, request):
try:
# 去缓存找数据
conn = get_redis_connection("intelligent") # 获取到了redis数据库的连接
msg = conn.get("EntitiesWord") # 去数据库找键是"EntitiesWord"的数据
if msg: # 如果有数据就直接返回
return Response(json.loads(msg))
# 缓存没有去数据库找并加入缓存
msg = list(EntitiesWordTable.objects.all().values("type", "content"))
for i in msg:
i['content'] = eval(i['content'])
logger.infolog("EntitiesWordView", "userid:{}".format(request.user.id))
conn.set("EntitiesWord",json.dumps(msg), random.randint(36000,72000))
return Response(msg)
except Exception as e:
logger.errlog("EntitiesWordView", str(e), "")
raise APIException(str(e))
这里的conn = get_redis_connection(“intelligent”)就获取到了settings中的intelligent数据库连接,可以把它当成是普通的redis连接,redis的各个函数它都有,在这个项目中,使用最多的是Hash和String操作
1、String 操作
单个设置 set get
conn.set("EntitiesWord",json.dumps(msg), random.randint(36000,72000)) # 设置过期时间为10小时到20小时之间随机
conn.get("EntitiesWord") # 去数据库找键是"EntitiesWord"的数据
2、Hash操作
Hash操作是无法设置过期时间的,设置值后它的过期时间为-1,无法通过设置改变,本次用到它的原因是我可以根据设置的键它里面的键值对都删除掉,而不用管键值的key与value是多少
# 获取缓存
conn = get_redis_connection("resume")
data = conn.hget("resumelist:{}".format(request.user.id),str(request.query_params))
if data:
return Response(json.loads(data))
# 加入缓存
conn.hset("resumelist:{}".format(request.user.id),str(request.query_params),json.dumps({"failnums":failnums,"data":redict_datas}))
这里str(request.query_params)是用户Get请求的参数,因为参数的组合种类非常多,且更换缓存内容是手动更新而不是过期更新的,所以使用了Hash方式
在其他地方,触发清除缓存的操作
if conn.hkeys("resumelist:{}".format(userid)):
conn.hdel("resumelist:{}".format(userid), *conn.hkeys("resumelist:{}".format(userid)))
conn.hkeys(“resumelist:{}”.format(userid)) 获取到的是Hash操作的键的列表,
conn.hdel(“resumelist:{}”.format(userid), *conn.hkeys(“resumelist:{}”.format(userid))) 是将列表解开后全部删除
除了批量删除,也可以单个删除
if conn.hexists(str(userid), "getBachResult"):
conn.hdel(str(userid), "getBachResult")
前段时间用redis的队列做了异步任务,后来将异步任务放到了rabbitmq上,有机会再说