redis系列(五) redis 缓存设计

1. 缓存的收益与成本

1.1收益

  1. 加速读写:因为缓存通常都是全内存的(例如Redis、Memcache),而存储层通常读写性能不够强悍(例如MySQL),通过缓存的使用可以有效地加速读写,优化用户体验。

  2. 降低后端负载:帮助后端减少访问量和复杂计算(例如很复杂的SQL语句),在很大程度降低了后端的负载。

  3. 使用redis带来的成本

  • 数据不一致性:缓存层和存储层的数据存在着一定时间窗口的不一致性,时间窗口跟更新策略有关。

  • 代码维护成本:加入缓存后,需要同时处理缓存层和存储层的逻辑,增大了开发者维护代码的成本。

  • 运维成本:以Redis Cluster为例,加入后无形中增加了运维成本。

  1. 使用场景

  • 开销大的复杂计算:以MySQL为例子,一些复杂的操作或者计算(例如大量联表操作、一些分组计算),如果不加缓存,不但无法满足高并发量,同时也会给MySQL带来巨大的负担。

  • 加速请求响应:即使查询单条后端数据足够快,那么依然可以使用缓存,以Redis为例子,每秒可以完成数万次读写,并且提供的批量操作可以优化整个IO链的响应时间

2. 缓存更新策略

2.1 内存溢出淘汰策略

当Redis所用内存达到maxmemory上限(used_memory>maxmemory)时会触发相应的溢出控制策略。具体策略受maxmemory-policy参数控制。

Redis支持6种策略:

1)noeviction:默认策略,不会删除任何数据,拒绝所有写入操作并返回客户端错误信息(error)OOM command not allowed when used memory,此时Redis只响应读操作。

2)volatile-lru:根据LRU算法删除设置了超时属性(expire)的键,直到腾出足够空间为止。如果没有可删除的键对象,回退到noeviction策略。

3)volatile-random:随机删除过期键,直到腾出足够空间为止。

4)allkeys-lru:根据LRU算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。

5)allkeys-random:随机删除所有键,直到腾出足够空间为止。

6)volatile-ttl:根据键值对象的ttl属性,删除最近将要过期数据。如果没有,回退到noeviction策略

内存溢出控制策略可以采用config set maxmemory-policy{policy}动态配置。

写命令导致当内存溢出时会频繁执行回收内存成本很高,如果Redis有从节点,回收内存操作对应的删除命令会同步到从节点,导致写放大的问题。

2.2  过期删除

2.2.1 惰性删除

Redis的每个库都有一个过期字典,过期字典中保存所有key的过期时间。当客户端读取一个key时会先到过期字典内查询key是否已经过期,如果已经超过键,会执行删除操作并返回空。,这种策略是出于节省CPU成本考虑,但是单独用这种方式存在内存泄露的问题,当过期键一直没有访问将无法得到及时删除,从而导致内存不能及时释放。

2.2.2 定时删除

Redis内部维护一个定时任务,默认每秒运行10次。通过hz修改运行次数。定时任务中删除过期键逻辑采用了自适应算法,根据键的过期比例、使用快慢两种速率模式回收键。ServerCron

慢模式:定时任务执行时间超过25毫秒自动退出

快模式:上次执行时间超过25毫秒,则采用快模式,快模式下超时时间为1毫秒且2秒内只能运行1次。

3. 缓存穿透 缓存雪崩 缓存击穿

请参考:https://blog.csdn.net/qq_38130094/article/details/80191666

发布了55 篇原创文章 · 获赞 3 · 访问量 5232

猜你喜欢

转载自blog.csdn.net/qq_38130094/article/details/103842216