0
点赞
收藏
分享

微信扫一扫

通过Jmeter准备压测数据-mysql示例

sunflower821 03-31 20:00 阅读 2

Redis面经

  • Redis缓存穿透、缓存击穿和缓存雪崩及解决方案
    • 概述
    • 缓存穿透详解及解决方案
    • 缓存击穿详解及解决方案
    • 缓存雪崩详解及解决方案
  • Redis持久化机制
    • 什么是数据持久化?
    • Redis数据持久化概述
    • RDB持久化的优缺点
    • AOF持久化
    • 混合持久化

Redis缓存穿透、缓存击穿和缓存雪崩及解决方案

概述

三者的根本原因在于,Redis命中率下降,请求直接打在了数据库上。
在正常的情况下,大部分的资源请求都可以被Redis响应,没有被Redis响应的小部分请求会转向数据库,这样的话,数据库DB的压力不会太大,是可以正常工作的。然而,如果大量高并发请求同时打在了Redis上,请求并没有在Redis上找到相应的资源,也就是Redis没有响应,命中率降低。这些请求就只能转向数据库,在大量高并发的请求之下,导致数据库压力瞬间增大,从而造成数据库服务器卡死或者宕机。而导致Redis命中率下降的原因就可以分为三种,分别对应着缓存穿透、缓存击穿和缓存雪崩。

缓存穿透详解及解决方案

缓存穿透是指请求根本不存在的资源,数据库中没有,Redis中更不会有。例如,客户端发送大量无法响应的请求,类似于“http://localhost:8080/user/199?id=-1”,数据库本身就不存在id=-1的用户数据,Redis中就更不可能存在,那么这些请求就得不到响应,就会直接打在数据库上。缓存穿透通常是黑客所为,黑客发送大量的无法响应的请求给服务器,由于请求的资源根本不存在,从而导致数据库压力过大而卡死或宕机。
解决方案

  1. 对空值进行缓存:类似于上面的例子,由于数据库中没有id=-1的用户数据,可以在Redis中对它进行缓存,即key=-1,value=null。这样的话,当请求到达Redis的时候就会直接返回一个null给客户端,避免了Redis无法响应的问题。需要注意的是,对空值进行缓存时,key的过期时间不能设置太长,以免占用太多Redis资源,而且对空值进行缓存是一种很被动的防御方式,当遇到黑客请求大量不存在的资源就需要写入大量的null值到Redis中,可能会导致Redis内存不足。
  2. 实时监控,拒绝黑客攻击:当Redis命中率出现大大下降的情况,就要配合运维人员对访问对象和访问数据进行分析排查,从而进行黑名单的设置,拒绝黑客攻击。
  3. 使用布隆过滤器:使用BitMap作为布隆过滤器,将可以访问的资源通过简单的映射关系放到布隆过滤器中,例如哈希计算。当请求来临时,首先将请求放入布隆过滤器进行判断,如果有相应资源则放行,如果没有则直接拦截。需要注意的是,布隆过滤器是有一定误差的,一般需要配合其他限制来解决缓存穿透问题。
  4. 接口校验。类似于用户权限的拦截,对于id=-1这种无效请求直接进行拦截,不允许这些请求到达Redis和数据库上。

缓存击穿详解及解决方案

缓存击穿是指Redis中某个热点key过期,此时有大量的用户访问该key,大量高并发的对于该key的请求没有得到Redis的响应,就会转向数据库,导致数据库服务器瘫痪。
解决方案

  1. 提前对热点数据进行设置:在一些新闻资讯平台或软件上,需要对热点数据提前设置在Redis缓存中。
  2. 监控数据,适时调整:监控哪些数据是热门数据,实时调整key的过期时长。
  3. 使用锁机制:只有一个请求可以获得互斥锁,请求在数据库中查询数据并将结果返回给Redis,这样其他请求就可以从Redis中得到响应。

缓存雪崩详解及解决方案

缓存雪崩像是缓存击穿的promax版,Redis中的key集体过期,相当于Redis中的大部分数据被清空了或者说是失效了,那么此时Redis中由于没有相应数据就无法响应大量高并发的请求,命中率急剧下降,请求都打在了数据库上,数据库服务器直接崩溃。
解决方案

  1. 将失效时间分散开:使用自动生成随机数使得key的过期时间是随机的,防止集体过期。
  2. 使用多级缓存架构:使用Nginx缓存+Redis缓存+其他缓存,不同层使用不同的缓存,提高了系统的可靠性。
  3. 设置缓存标记:记录缓存数据是否过期,如果过期就会触发另外的后台线程实时更新过期的key。
  4. 使用锁或者队列的方式:请求不到的资源加上排它锁,其他请求就只能等待。

Redis持久化机制

什么是数据持久化?

数据持久化就是将数据从内存写入磁盘,目的在于防止数据丢失。内存中的数据在服务器重启或者断电时会丢失,而磁盘中的数据不会,为了确保系统的稳定性,需要进行数据的持久化操作。

Redis数据持久化概述

Redis是一种基于内存的数据库,同时,也支持将数据写入数据库,这个过程就叫做Redis数据持久化。
Redis持久化方法主要有以下三种:

  1. 快照方式(Redis database,RDB):将某一时刻的内存数据生成Snapshot快照,以二进制的形式写入磁盘,由于是以二进制的方式写入磁盘,因此效率很高,但是一旦Redis意外终止,就会导致部分数据丢失。
  2. 命令追加方式(Append only file,AOF):记录Redis数据的所有写操作指令,以文本的形式追加到AOF文件中,由于是以文本的形式写入,因此效率比较低,但是AOF文件记录了所有写操作指令,在Redis服务重启时,只需要从头到尾重新执行一遍AOF文件中的命令即可回复数据保证数据的完整性。
  3. 混合持久化方式:Redis4.0之后新增的方式,结合了RDB和AOF的优点,将RDB 文件和 AOF 日志文件存在一起,这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。在写入的时候,先把当前数据以 RDB 形式写入文件的开头,再将后续的操作命令以 AOF 的格式存入文件,这样既能保证 Redis 重启时的速度,又能降低数据丢失的风险。因此,混合持久化适用于对数据安全性和性能要求较高的场景。

RDB持久化的优缺点

优点

  1. RDB文件数据以二进制的形式存在,占用内存小,文件更加紧凑,适合于文件备份。
  2. RDB适合灾难恢复,由于其文件紧凑,可以更高效率地传输给远程服务器提供Redis服务。
  3. RDB可以提高Redis的运行速度,每次持久化Redis主线程会fork出一个子进程,子进程负责快照持久化,将内存数据存储到磁盘,而Redis主进程继续负责处理客户端请求,不会执行磁盘I/O等操作。
  4. 与AOF格式文件相比,RDB文件可以更快地重启,因为二进制方式写入磁盘的效率要比文本方式写入磁盘的效率要高。

缺点

  1. 由于RDB只能保存某一时间段的数据,因此一旦中途Redis服务意外终止,则会丢失一段时间的Redis数据。
  2. RDB需要经常fork()才能使用子进程将内存数据持久化在磁盘中,一旦数据集过大,fork()会很耗时,如果再加上CPU性能不佳,可能会导致Redis停止为客户端服务几毫秒甚至一秒钟。

AOF持久化

优点

  1. AOF持久化保存的数据更加完整。因为AOF提供了三种保存策略:“每次操作保存、每秒钟保存一次和跟随系统持久化策略保存”,其中,每秒钟保存一次是AOF的默认保存策略,从数据安全性和性能方面来讲都是很不错的选择,即使发生意外,最多丢失一秒钟的数据。
  2. AOF采用命令追加的写入方式,不会出现文件损坏问题,即使有意外情况,也可以使用redis-check-aof工具轻松修复。
  3. AOF持久化文件很容易解析,因为它是把所有Redis键值操作命令以文本的形式写入磁盘,即使不小心使用flush all命令删除了所有的键值信息,只要使用AOF文件删除最后的flush all命令,重启Redis服务即可恢复之前误删的数据。

缺点

  1. 对于相同的数据集,AOP文件要大于RDB文件。
  2. 在Redis负载比较高的情况下,RDB要比AOF性能更好。
  3. RDB使用快照持久化数据,AOF使用命令追加到AOF文件,从数据完整性和可靠性的角度来看,RDB比AOF更加健壮、易于维护。

混合持久化

优点
既能提高Redis服务启动的速度,还能保证数据的完整性和安全性,降低了丢失大量数据的风险。
缺点

  1. AOF文件中添加了RDB格式的内容,使得AOF文件可读性变差。
  2. 混合持久化不能在Redis4.0之前的版本使用,兼容性差。
举报

相关推荐

0 条评论