redis数据库缓存详解

redis需求背景

  • 缓存不是必须得,因为需要提高性能而增加得。

  • 目标:为了减少磁盘数据库得查询,不如mysql得查询,更多得从内存中读取数据

    mysql查询数据需要1s左右,1s以上通常认为慢查询,而rides支持得操作性能1s可以才做(1w~10w)得数据

  • 使用场景:
    1.使用前提要读取频繁
    2.数据不经常变化,基本一定做缓存处理
    3.数据可能会频繁变化,如果数据是产品核心数据,可以考虑构建缓存,缓存时间短,即使缓存五分钟,也能减少很大程度得数据库查询操作,可以提升性能。

缓存架构

多级缓存

  • 本地缓存
    全局变量
    orm框架queryset查询集保存,起到本地保存缓存作用
  • 外部缓存
    可以构建多级缓存
    redis,mencached
    缓存数据得保存方式
  • 序列化字符串
setex('user:{user_id}:info')
setex (''user:1:info,expiry,json.dumps(user_dict))
  • redis得其他数据类型,如hash,set,zset
# 使用hash优点:读写时序列化转换,可以更行内部数据
# 缺点:相比字符串,采用复合结构存取空间占用大
hset('user:1:info',user_dict)

缓存有效期

缓存数据一定要设置有效期,原因:

  • 及时清理可以节省空间
  • 保证数据得一致性,保证mysql中数据与reids中得数据,在更行数据之后还能一直,虽然在一定得时间内redis与mysql中得数据不同,但是过了有效期后redis会清理数据,再次查询数据时会形成新的缓存数据,redis与mysql又相同了.
redis的有效期策略

通用的有效策略:

  • 定时过期
set a 100 有效期10min
set  b 100 有效期20min

开启一个计时器,当有效期到达之后 清理数据,可以理解为每个数据都需呀一个定时器。
缺点:耗费性能

  • 惰性过期
    保存数据 设置有效期后 不主动维护这个数据的有效期,不记时,只有再次访问这个数据的时候,判断数据是否到期,如果到期清理并返回空,如果没到期,返回数据。

  • 定期过期
    周期性的检查那些数据过期 那些数据没过期,比如每100ms 判断那些数据过期,如果有过期立马清理。

redis的有效期策略:惰性过期+定期过期
redis实现定期过期时,还不是查询所有数据,而是每100ms随机选出一些数据判断是否过期,再过100ms在随机选出一些判断。

缓存淘汰

背景:redis的数据有效期策略不能保证数据真正的即使被清理,可能照成空间浪费,再有新的数据时候,没地方可以存储,为了存储新的数据,需要清理redis中的一批新的数据,腾出空间保存新的数据。

通用的内存淘汰算法:LRU&LFU

  • LRU(least recently used,最近最少使用)
    思想:认为越是最近用过的数据,接下来使用的机会越大,应该清理那些很久以前使用过的数据
cache_data  = [
	cache1   时间最近
	cache2
	cache3
	cache4 时间最长    # 被清理
]

操作过cache3
cache_data  = [
	cache3
	cache1   时间最近
	cache2
	cache4
]
操作过cache4
cache_data  = [
	cache4
	cache3
	cache1   时间最近
	cache2
]
  • LFU(least frequently used)最少使用
    思想:认为使用次数越多的数据,接下来使用的机会越大,应该清理那些使用次数少的数据
cache_data  = [
	cache1 :200
	cache2:5
	cache3:150
	cache4:1   # 被清理
]

Redis的内存淘汰策略(3.x版本以后)

  • noeviction:当内存不足以写入数据时,新写入操作会报错,默认为noevition。
  • allkeys-lru:当内存不足时写入新数据时,在键空间中,移除最近最少使用的key。
  • allkeys-random:当内存不足写入新数据时,在键空间时,随机移除某个key。
  • volatile-lru:当内存不足写入新数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
  • vlatile-random:当内存不足以写入新数据时,在设置了过期时间的键空间中,随机移除某个key。
  • volatile-ttl:当内存不足以写入新数据时,在设置了过期时间的键空间中,有更早时间的key优先移除。
    redis中的配置
maxmemorry  指名redis使用最大的内存上限
maxmemorry-policy volati-lru 指名内存淘汰策略

缓存模式

应用程序如何使用缓存

  • 读缓存
    场景:需要频繁查询数据库的场景
    方式:在应用程序与mysql数据库中间假设redis作为缓存,保存数据的时候先保存到缓存redis中,并不直接保存到redis中,后续在从redis中同步数据到mysql中。
  • 写缓存
    场景:需要频繁保存数据的场景
    方式: 在应用跟程序与mysql数据库中间架设redis作为缓存,保存数据的时候先保存到redis中,并不直直接保存到mysql中,后续在从reids中同步数据到mysql在中
    读缓存大的数据同步问题:
    修改了mysql中得数据,如何处理redis中缓存得数据
  • 先更新数据库,在更新缓存
  • 先删除缓存,在更新数据库
  • 先更新数据库,在删除缓存 发生问题得机率小,负面影响最小

缓存使用过程中可能存在得问题

  • 缓存穿透
    问题:在查询不存在得数据时,缓存为空,数据空也为空,每次访问都会落到数据库,导致数据库性能变差
    解决:在缓存中保存不存在得数据,不如以-1保存,表示数据不存在,可以拦截这种攻击,减少数据库查询
  • 缓存雪崩
    问题:在缓存数据时,设置得同一时效,刚好并发访问,数据全部失效,导致查询缓存为空,直接访问数据库,数据库扛不住,会崩溃
    解决:1.将数据有效期增加偏差值,让同一批数据在不同时间段失效。
    2.假设多级缓存,每级缓存时效不同。
    3.以保护数据库出发,为数据库操作添加锁

你可能感兴趣的:(mysql)