简述下redis的其他机制

本文详细介绍了Redis的持久化机制,包括RDB和AOF两种方式,以及Redis如何处理缓存雪崩、缓存穿透、缓存击穿等问题。此外,还讨论了缓存预热、缓存更新和缓存降级策略,以及Redis的热点数据和冷数据处理。文章还探讨了Redis的过期策略和内存淘汰机制,并提出了Redis常见性能问题的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、Redis持久化机制

Redis是一个支持可持久化的内存数据库,通过持久化机制把你内存的数据同步到硬盘文件来保证其持久化。当Redis重启的时候会将硬盘中的文件重新加载到内存之中,来达到数据回复的问题。
实现方式:单独创建一个fork()进程,将当前的父类进程的数据库数据复制到子进程的内存之中,然后由子进程将其写入到临时文件中。,持久化进程结束后能将临时文件替换上次的快照文件,然后子进程退出内存释放。
快照(rdb)
rdb是默认的持久化方式。Snapshot将内存中文件以快照的方式保存到硬盘的二进制文件并生成dump.rdb文件并通过配置文件中save参数来定义快照的周期。
Redis 使用操作系统的多进程 COW(Copy On Write) 机制来实现快照持久化,
fork(多进程)
Redis在持久化的过程中会调用glibc的函数fork产生一个子进程,快照持久化就可以完全交给子进程进行处理,父进程可以继续处理客户的请求。子进程在刚开始创建的时候和父进程共享内存里的数据段。这样内存就不会由太大的变化。
AOF:
AOF 日志存储的是 Redis 服务器的顺序指令序列,AOF 日志只记录对内存进行修改的指令记录。
Redis会将每一个收到的写命令都通过Write函数追加到文件最后,当Redis重启是会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

二、缓存雪崩、缓存穿透、缓存击穿、缓存预热、缓存更新、缓存降级

缓存雪崩

是指在某一个时间段,缓存集中过期失效。所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。
目前最多的解决方案就是加锁,但是又会有新的问题,因为redis是单线程如果频繁加锁优惠严重影响到其性能。另一种方式就是的队列的方法来保证不会有大量的线程对数据库一次性读写,从而避免失效时大量的并发请求落在底层存储系统上。

缓存穿透

简单的说就是用户想要查询数据,数据库中不存在这样的数据,那么缓存中也一定不会存在这样的数据,用户在进行查询操作的时候就会先要访问缓存,缓存中查询不到的话会再在数据库中进行查询再返回空值,这样就会导致进行两次查询降低效率。
解决方法有两种:
第一种布隆过滤器,将所有可能存在的数据hash到一个足够大的bitmap中,一个一定不存在的就会被bitmap过滤掉(空间换时间)
第二种暴力方式,当用户查询返回为空的时候,仍然将空进行缓存、但其过期的时间相对较短,通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。打个比喻在一堆人在一起开会,我找的人不在这个会议中,我为这个人准备一个椅子,没过一段时间就会把这个椅子撤走。

缓存击穿

是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据。
解决方式就是上锁,当我这个节点被访问的时候我将其变成原子操作,这个访问结束才可以让下一个访问进入。

缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。解决用户直接访问数据库。
解决思路:
1、直接写个缓存刷新页面,上线时手工操作下;
2、数据量不大,可以在项目启动的时候自动进行加载;
3、定时刷新缓存;

缓存更新

除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:
定时任务去清理过期的缓存;
提供手动清理缓存的接口。
当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
上面的这几个方案各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的;第二种人工成本太高;第三种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂。具体使用场景还得结合业务来区分对待

缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。
降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。
以参考日志级别设置预案:
(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
(2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
(3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。
主要目的是防止Redis发生故障,连带数据库一起雪崩。对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

三、热点数据和冷数据

热点数据:经常被访问到的数据
冷数据:不经常被访问,有的甚至没有被访问就已经被清出缓存了。
首先我们要明白一个道理只有一个数据被访问两次及以上的时候才有意义,否则数据缓存可能会更加的消耗时间和资源。
那存不存在,修改频率很高,但是又不得不考虑缓存的场景呢?有!比如,这个读取接口对数据库的压力很大,但是又是热点数据,这个时候就需要考虑通过缓存手段,减少数据库的压力,比如我们的某助手产品的,点赞数,收藏数,分享数等是非常典型的热点数据,但是又不断变化,此时就需要将数据同步保存到Redis缓存,减少数据库压力。

四、redis的过期策略以及内存淘汰机制

redis采用的是定期删除+惰性删除策略。
定期删除:redis默认每隔100ms进行一次检查,查找是否有过期的key值,在检查的过程并不是进行全部遍历而是随机抽取,这样虽然省下了大量的时间但是优惠导致很多过期的key无法被删除,这样我们就开始进行惰性删除。惰性删除是每次我查询取值的时候都会顺道检查一下这个key值是否过期,如果过期就将其删掉。

当Redis的内存使用达到设置的内存上限时就会触发内存淘汰机制,按照特定的淘汰算法进行数据清理,释放内存。
具体的内存淘汰算法有一以下几种:
noeviction:不淘汰,内存不足时, 新写入会报错。
allkeys-lru:LRU,内存不足时,淘汰最近最少使用的key。
2allkeys-random:随机,内存不足时,在所有key中随机选择一个key淘汰。
volatile-lru:过期时间内LRU,内存不足时,在设置了过期时间的key中,淘汰最近最少使用的key。
volatile-random:过期时间内随机,内存不足时,在设置了过期时间的key中,随机选择一个key淘汰。
volatile-ttl:更早过期时间,内存不足时,在设置了过期时间的key中,选择有更早过期时间的key淘汰。
Redis默认使用的是LRU算法,需要注意的是LRU并不是多有的keys进行LRU,而是在所有的key中随机选择3个key,在这3个key中进行LRU算法选择;3个这个个数可以在redis配置文件中进行配置maxmeory-samples选项。
在大规模并发的情况下,我们可以使用集群方式进行内存的扩充。

五、Redis 常见性能问题和解决方案

就是对上述问题的一种总结
(1) Master 最好不要做任何持久化工作,如 RDB 内存快照和 AOF 日志文件
(2) 如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性, Master 和 Slave 最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定


# 参考博客 https://www.cnblogs.com/toutou/p/redis_question.html https://blog.youkuaiyun.com/Butterfly_resting/article/details/89668661 https://www.likecs.com/show-66988.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值