本文在实际工作项目中,缓存已成为高并发、高性能体系结构的重要组成部分,而Redis为什么可以用作缓存? 首先,缓存的主要特征有以下两个
在分层系统中,内存/CPU访问性能良好,缓存数据饱和。 良好的数据处置机制具有Redis自然具有的两个特点。 Redis基于内存操作,具有完整的数据处置机制,非常适合用作缓存组件。
其中,基于内存操作,容量为32-96GB,操作时间平均为100ns,操作效率高。 另外,数据丢弃机制很多,Redis 4.0以后的8种正在促使Redis作为缓存适用于很多场景。
为什么Redis缓存需要数据处置机制? 有哪八种数据处置机制?
数据销毁机制Redis缓存是基于内存实现的,但其缓存容量有限,如果缓存已满,Redis该如何处理?
如果Redis的缓存已满,则Redis需要一种缓存数据销毁机制,可以按一定的销毁规则选择并删除一些数据,以重用缓存服务。 那么,Redis使用什么处置策略来清除数据?
从Redis 4.0开始,Redis缓存处置策略分为六大类,分为三类:
不丢弃数据
noeviction,不销毁数据且缓存已满后,Redis将返回错误而不提供服务。 要设置过期的键值对,请单击,
volatile-random从设置过期日期的密钥和值对中随机删除volatile-ttl,设置过期日期的密钥和值对根据过期日期的优先级被删除,过期日期越早,volatile-random删除的时间越早。 volatile-lru根据延迟(LRU )算法过滤过期的键值对。 最近,它最少用于过滤数据中的volatile-lfu。 使用lfu(leastfrequentlyused )算法选择已过期的键-值对,并针对使用频率最低的所有键-值对,选择、
allkeys-random,从所有键值对中随机选择并删除数据allkeys-lru,使用LRU算法过滤所有数据,使用LFU算法过滤所有数据
Note: LRU (最近使用的最小值,最近使用)和LRU维护双向链表。 链表的开头和结尾分别表示MRU端和LRU端,分别表示最近最常用和最不常用的数据。
在实际实施LRU算法时,必须使用链表来管理所有缓存数据,这会产生额外的空间开销。 此外,如果数据被访问,则必须在链表中将该数据移动到MRU端。 大量数据被访问时,链表的移动操作会变多,需要时间,Redis缓存的性能会下降。
其中,LRU和LFU是基于Redis的对象结构redisObject的LRU和refcount属性安装的:
类型描述符{ unsigned type :4; 未编码:4; //对象上次访问的时间unsigned lru:LRU_BITS;/* lr utime (relativetogloballru _ clock ) or*lfudata ) least significant8bits frequency//引用次数) andmostsignificant 16 bitsanata } robj; redis LRU使用redisObject中的LRU记录上次访问的时间,随机选择参数最大内存-样本配置的数量作为候选集,然后选择并丢弃其中LRU属性值最小的数据。
在实际项目中,该如何选择数据处置机制呢?
优先选择allkeys-lru算法,将最近访问最多的数据保留在缓存中,以提高APP应用程序的访问性能。 开销数据使用volatile-lru算法,开销数据不设置缓存过期时间,其他数据设置过期时间,并根据LRU规则进行过滤。 了解Redis缓存的处置机制后,看看Redis作为缓存有多少模式?
Redis缓存模式Redis缓存模式可以分为只读缓存和读/写缓存,具体取决于是否接收到写请求。
只读缓存:只处理只读操作,所有更新操作都在数据库中,因此不存在数据丢失的风险。
缓存辅助模式
读写缓存、读写操作都在缓存中执行,一旦发生停机故障,数据就会丢失。 将数据高速缓存回数据库有以下两种同步和异步:
同步:重点是访问性能低,确保数据的可靠性
读模式写模式异步:重点是存在数据丢失风险,提供低延迟访问
写入隐藏模式
Cache 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模式), 读操作都发生在缓存中,数据不一致只会发生在删改操作上(新增操作不会,因为新增只会在数据库处理),当发生删改操作时,缓存将数据中标志为无效和更新数据库 。因此在更新数据库和删除缓存值的过程中,无论这两个操作的执行顺序谁先谁后,只要有一个操作失败了就会出现数据不一致的情况。
最后看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。
开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题。
注意:不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友,直接戳这里即可免费下载
互联网工程师必备的面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。
480)]
互联网工程师必备的面试1000题
而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题。