redis+mysql实现缓存
需求:假如我们的需求是当多个⽤户可能同时上传⼀组数据并去重后保存到数据库mysql的时候,会出现卡顿的现象是因为⾼并发插⼊数据的时候⾸先会执⾏filter查询语句,其次再执⾏create,⼤量的查询使得数据库压⼒很⼤,这时就需要做缓存,把查询的逻辑放到缓存中去执⾏,例如(原始的去重查询⼊库逻辑):
version_info = VersionInfo.objects.filter(
cluster_id=form_data['cluster_id'],
hostname=form_data['hostname'],
pkg_name=form_data['pkg_name'])
if ists():
version_info.update(**form_data)
return version_info[0]
else:
return ate(**form_data)
解决⽅案:redis+mysql
具体实现细节:
1.⾸先将上传的数据经过redis;
2.在redis中通过常见的数据类型set进⾏去重并添加到list中;
3.携带modify_time设置为str类型;
4.最后将去重后的数据定时写⼊到mysql中
代码技术分析:
第⼀步:将数据存⼊到redis进⾏去重做缓存(celery异步)
(1)接⼝中正常的post请求,将请求到的数据进⾏⽇常的遍历及form校验或者使⽤django中的序列化器校验
(2)如何具体的对上传的数据进⾏缓存处理,缓存信息进⾏异步调⽤
(3)缓存上传到redis的具体信息:
1>:需要连接redis:_redis_connection('default')
2>:准备redis的键的构造
3>:遍历上传的所有的数据,使⽤⼀些特殊符号,⽐如“#”拼接⼀些可能出现重复的参数
4>:然后判断redis的set类型中value值是否存在,不存在则直接添加到set中, 最后将整个数据push到list中:
if not redis_conn.sismember(set的键, 拼接的值):
redis_conn.sadd(set类型的键, 拼接的值)
redis_conn.lpush(list类型的键, redis遍历的数据)
5>:万⼀所有的数据需要修改时间的话则在这⾥设置redis的str类型,准备modify_time的键,根据拼接的值作为str类型的值
redis_conn.set(修改时间的键,拼接的值)
6>:给redis中存储的set类型和list类型分别设置过期时间,使⽤expire()函数
# 设置过期时间:截⽌今天晚上12点之前
expire_seconds = (
django.utils.day().replace(hour=23, minute=59, second=59, microsecond=999999) - w()
)
# 分别给两种类型设置过期时间
pire(构造好的set的键, expire_seconds)
pire(构造好的list的键, expire_seconds)
第⼆步:定时将redis缓存中的数据备份到mysql中(celery异步)
(1)将缓存中的数据持久化到数据库中并清除缓存数据
(2)根据redis的list类型中存储的数据个数简单的使⽤xrange()函数遍历
for i in xrange(redis中list的个数):
(3)具体实现逻辑分析
for i in xrange(redis中的list个数):
# 获取redis中的list数据 = redis_conn.rpop(根据redis中list的键)
version_intro = {
redis支持的五种数据类型'去重的键': 获取redis中的list数据['去重的键'],
'去重的键': 获取redis中的list数据['去重的键'],
'去重的键': 获取redis中的list数据['去重的键'],
}
# 获取modify_time,根据拼接的值进⾏获取
modify_time = 拼接后获取的值
if modify_time is None:
redis_conn.lpush(获取到的redis中list类型的键, 获取redis中的list数据)
continue
获取redis中的list数据.update({
'modify_time': modify_time
})
mysql中存在的表的object = 表名.objects.filter(**version_intro)
if mysql中存在的表的object:
mysql中存在的表.object.update(**获取redis中的数据)
else:
mysql中存在的表.ate(**获取redis中的数据)
获取redis中的数据.pop('modify_time')
# 将遍历出来的数据重新lpush到list类型中
redis_conn.lpush(redis中list类型的键, 获取redis中的数据)
(4)celery定时任务中每隔⼀段时间定时备份到mysql中
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论