网站网页设计培训班,虚拟主机搭建网站源码,ajax 效果网站,怎么做赛事直播网站在实际的工作项目中#xff0c; 缓存成为高并发、高性能架构的关键组件 #xff0c;那么Redis为什么可以作为缓存使用呢#xff1f;首先可以作为缓存的两个主要特征#xff1a;在分层系统中处于内存/CPU具有访问性能良好#xff0c;缓存数据饱和#xff0c;有良好的数据淘…在实际的工作项目中 缓存成为高并发、高性能架构的关键组件 那么Redis为什么可以作为缓存使用呢首先可以作为缓存的两个主要特征在分层系统中处于内存/CPU具有访问性能良好缓存数据饱和有良好的数据淘汰机制由于Redis 天然就具有这两个特征Redis基于内存操作的且其具有完善的数据淘汰机制十分适合作为缓存组件。其中基于内存操作容量可以为32-96GB且操作时间平均为100ns操作效率高。而且数据淘汰机制众多在Redis 4.0 后就有8种了促使Redis作为缓存可以适用很多场景。那Redis缓存为什么需要数据淘汰机制呢有哪8种数据淘汰机制呢数据淘汰机制Redis缓存基于内存实现的则其缓存其容量是有限的当出现缓存被写满的情况那么这时Redis该如何处理呢Redis对于缓存被写满的情况Redis就需要缓存数据淘汰机制通过一定淘汰规则将一些数据刷选出来删除让缓存服务可再使用。那么Redis使用哪些淘汰策略进行刷选删除数据在Redis 4.0 之后Redis 缓存淘汰策略62种包括分成三大类不淘汰数据noeviction 不进行数据淘汰当缓存被写满后Redis不提供服务直接返回错误。在设置过期时间的键值对中volatile-random 在设置过期时间的键值对中随机删除volatile-ttl 在设置过期时间的键值对基于过期时间的先后进行删除越早过期的越先被删除。volatile-lru 基于LRU(Least Recently Used) 算法筛选设置了过期时间的键值对 最近最少使用的原则来筛选数据volatile-lfu 使用 LFU( Least Frequently Used ) 算法选择设置了过期时间的键值对, 使用频率最少的键值对,来筛选数据。在所有的键值对中allkeys-random 从所有键值对中随机选择并删除数据allkeys-lru 使用 LRU 算法在所有数据中进行筛选allkeys-lfu 使用 LFU 算法在所有数据中进行筛选imgNote: LRU( 最近最少使用Least Recently Used)算法 LRU维护一个双向链表 链表的头和尾分别表示 MRU 端和 LRU 端分别代表最近最常使用的数据和最近最不常用的数据。LRU 算法在实际实现时需要用链表管理所有的缓存数据这会带来额外的空间开销。而且当有数据被访问时需要在链表上把该数据移动到 MRU 端如果有大量数据被访问就会带来很多链表移动操作会很耗时进而会降低 Redis 缓存性能。其中LRU和LFU 基于Redis的对象结构redisObject的lru和refcount属性实现的:typedef struct redisObject { unsigned type:4; unsigned encoding:4; // 对象最后一次被访问的时间 unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency // 引用计数 * and most significant 16 bits access time). */ int refcount; void *ptr; } robj; 复制代码 Redis的LRU会使用redisObject的lru记录最近一次被访问的时间随机选取参数maxmemory-samples 配置的数量作为候选集合在其中选择 lru 属性值最小的数据淘汰出去。在实际项目中那么该如何选择数据淘汰机制呢优先选择 allkeys-lru算法将最近最常访问的数据留在缓存中提升应用的访问性能。有顶置数据使用 volatile-lru算法 ,顶置数据不设置缓存过期时间其他数据设置过期时间基于LRU 规则进行筛选 。在理解了Redis缓存淘汰机制后来看看Redis作为缓存其有多少种模式呢Redis缓存模式Redis缓存模式基于是否接收写请求可以分成只读缓存和读写缓存只读缓存只处理读操作所有的更新操作都在数据库中这样数据不会有丢失的风险。Cache Aside模式image.png读写缓存读写操作都在缓存中执行出现宕机故障会导致数据丢失。缓存回写数据到数据库有分成两种同步和异步同步访问性能偏低其更加侧重于保证数据可靠性Read-Throug模式Write-Through模式异步有数据丢失风险其侧重于提供低延迟访问Write-Behind模式image.pngCache Aside模式查询数据先从缓存读取数据如果缓存中不存在则再到数据库中读取数据获取到数据之后更新到缓存Cache中但更新数据操作会先去更新数据库种的数据然后将缓存种的数据失效。而且Cache Aside模式会存在并发风险执行读操作未命中缓存然后查询数据库中取数据数据已经查询到还没放入缓存同时一个更新写操作让缓存失效然后读操作再把查询到数据加载缓存导致缓存的脏数据。Read/Write-Throug模式查询数据和更新数据都直接访问缓存服务缓存服务同步方式地将数据更新到数据库。出现脏数据的概率较低但是就强依赖缓存对缓存服务的稳定性有较大要求但同步更新会导致其性能不好。Write Behind模式查询数据和更新数据都直接访问缓存服务但缓存服务使用异步方式地将数据更新到数据库通过异步任务 速度快效率会非常高但是数据的一致性比较差还可能会有数据的丢失情况实现逻辑也较为复杂。在实际项目开发中根据实际的业务场景需求来进行选择缓存模式。那了解上述后我们的应用中为什么需要使用到redis缓存呢在应用使用Redis缓存可以提高系统性能和并发主要体现在高性能基于内存查询KV结构简单逻辑运算高并发 Mysql 每秒只能支持2000左右的请求Redis轻松每秒1W以上。让80%以上查询走缓存20%以下查询走数据库能让系统吞吐量有很大的提高虽然使用Redis缓存可以大大提升系统的性能但是使用了缓存会出现一些问题比如缓存与数据库双向不一致、缓存雪崩等对于出现的这些问题该怎么解决呢使用缓存常见的问题使用了缓存会出现一些问题主要体现在缓存与数据库双写不一致缓存雪崩: Redis 缓存无法处理大量的应用请求转移到数据库层导致数据库层的压力激增;缓存穿透访问数据不存在在Redis缓存中和数据库中导致大量访问穿透缓存直接转移到数据库导致数据库层的压力激增;缓存击穿缓存无法处理高频热点数据导致直接高频访问数据库导致数据库层的压力激增;缓存与数据库数据不一致只读缓存(Cache Aside模式)对于只读缓存(Cache Aside模式) 读操作都发生在缓存中数据不一致只会发生在删改操作上新增操作不会因为新增只会在数据库处理当发生删改操作时缓存将数据中标志为无效和更新数据库 。因此在更新数据库和删除缓存值的过程中无论这两个操作的执行顺序谁先谁后只要有一个操作失败了就会出现数据不一致的情况。总结出当不存在并发的情况使用重试机制消息队列使用当存在高并发的情况使用延迟双删除(在第一次删除后睡眠一定时间后再进行删除)具体如下操作顺序是否高并发潜在问题现象应对方案NOTE:延迟双删除伪代码redis.delKey(X) db.update(X) Thread.sleep(N) redis.delKey(X)读写缓存Read/Write-Throug、Write Behind模式 对于读写缓存写操作都发生在缓存中后再更新数据库只要有一个操作失败了就会出现数据不一致的情况。总结出当不存在并发的情况使用重试机制消息队列使用当存在高并发的情况使用分布锁。具体如下操作顺序是否高 并发潜在问题现象应对方案缓存雪崩缓存雪崩由于缓存中有大量数据同时过期失效或者缓存出现宕机大量的应用请求无法在 Redis 缓存中进行处理进而发送到数据库层导致数据库层的压力激增严重的会造成数据库宕机。对于缓存中有大量数据同时过期导致大量请求无法得到处理 解决方式数据预热将发生大并发访问前手动触发加载缓存不同的key 可以避免在用户请求的时候先查询数据库设置不同的过期时间让缓存失效的时间点尽量均匀双层缓存策略 在原始缓存上加上拷贝缓存原始缓存失效时可以访问拷贝缓存且原始缓存失效时间设置为短期拷贝缓存设置为长期服务降级 发生缓存雪崩时针对不同的数据采取不同的降级方案 比如非核心数据直接返回预定义信息、空值或是错误信息对于缓存出现宕机解决方式业务系统中实现服务熔断或请求限流机制防止大量访问导致数据库出现宕机缓存穿透缓存穿透数据在数据库和缓存中都不存在这样就导致查询数据在缓存中找不到对应key的value都要去数据库再查询一遍然后返回空相当于进行了两次无用的查询。当有大量访问请求且其绕过缓存直接查数据库导致数据库层的压力激增严重的会造成数据库宕机。对于缓存穿透解决方式缓存空值或缺省值当一个查询返回的数据为空时 空结果也将进行缓存并将它的过期时间设置比较短下次访问直接从缓存中取值避免了把大量请求发送给数据库处理造成数据库出问题。布隆过滤器( BloomFilter )将所有可能查询数据key哈希到一个足够大的bitmap中 , 在查询的时候先去BloomFilter去查询key是否存在如果不存在就直接返回存在再去查询缓存缓存中没有再去查询数据库 从而避免了数据库层的压力激增出现宕机。缓存击穿缓存击穿针对某个访问非常频繁的热点数据过期失效导致访问无法在缓存中进行处理进而会有导致大量的直接请求数据库从而使得数据库层的压力激增严重的会造成数据库宕机。对于缓存击穿解决方式不设置过期时间对于访问特别频繁的热点数据不设置过期时间。总结在大多数业务场景下Redis缓存作为只读缓存使用。针对只读缓存来说 优先使用先更新数据库再删除缓存的方法保证数据一致性 。其中缓存雪崩缓存穿透缓存击穿三大问题的原因和解决方式作者Ccww链接https://juejin.cn/post/6919271744754679815