Redis相关面试题
Redis是什么?都有哪些使用场景?
Redis是一个使用C语言开发的高速缓存数据库的。
Redis的使用场景:
- 记录帖子点赞数、点击数、评论数;
- 缓存近期热帖;
- 缓存文章详情信息;
- 发布订阅系统;
- 记录用户会话信息;
Redis有哪些功能?
- 数据缓存;
- 分布式锁;
- 支持数据持久化;
- 支持事务;
- 支持消息队列;
Redis和memcache有什么区别?
- 存储方式不同:memcache 把数据全部存储在内存之中,断电之后会挂掉,数据不能超过内存大小;Redis有部分存在硬盘上,这样能保证数据的持久化。
- 数据支持类型:memcache对数据类型支持相对简单;Redis有复杂的数据类型
- 使用底层模型使用不同:它们之间底层实现方式,以及与客户端之间通信的应用协议不一样,Redis自己构建了vm机制,因为一般的系统调用系统函数的话,会浪费一定时间去移动和请求。
- value值大小不同:Rdis最大可用达到512mb;memcache只有1mb.
Redis为什么会是单线程的?
因为cpu不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存或网络宽带。既然单线程容易实现,而且cpu又不会成为瓶颈那就顺理成章地采用单线程的方案了。
关于Redis的性能,官方网站也有,普通笔记本每秒轻松处理几十万的请求。
而且单线程并不代表就慢 nginx和 nodejs也都是高性能单线程的代表。
什么是缓存穿透?怎么解决?
Redis 缓存穿透指的是当请求的数据在缓存中不存在且在数据库中也不存在时,导致每次请求都绕过缓存直接查询数据库。由于数据库中也没有这个数据,查询每次都会失败,但这些无效请求可能会给数据库带来较大的压力,尤其是在请求频繁时,可能引发数据库负载过高甚至崩溃。
解决方案:
缓存空结果:当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后在访问这个数据库将会从缓存中获取,保护了后端数据源。
作用:当数据库中查询到的数据为空时,将该结果(如 null)缓存一段时间,防止频繁地查询同样的无效数据。
布隆过滤器:布隆过滤器就是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力;
作用:使用布隆过滤器提前判断请求的数据是否在数据库中存在,如果不存在则直接拒绝查询,从而减少对数据库的压力。
参数校验:对请求的参数进行严格校验,避免无效请求进入数据库查询环节,比如过滤掉明显无效的请求(如负数或不存在的 ID)。
什么是缓存击穿(量太大,缓存过期)
缓存击穿是只一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就会穿破缓存,直接请求数据库,就像在屏幕上挖了一个大洞。
当某个key在过期瞬间,有大量的请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访问数据库来查询最新的数据,并且回写缓存,会导致数据库瞬间压力过大。
问题描述:因为热点key设置了过期时间才会出现瞬间消失。
解决方案:
设置热点数据永不过期,从缓存层面上看,没有设置过期时间,就不会出现热点key过期后产生的问题。
使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,一次只需要等待即可,这种方式将高并发的压力转移到了分布式锁上,因此对分布式锁的考验也很大。
什么是Redis缓存雪崩?
缓存雪崩是指 某个时间段,缓存集中过期失效,Redis宕机。
产生雪崩的原因之一:
比如在写本文的时候,马上就要到双十一零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时,那么到了凌晨一点的时候,这批商品的缓存就会过期,而对这批商品的访问查询都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰,于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也挂掉的情况。
在自然形成的缓存雪崩中,是在某个时间段集中创建缓存,这个时候,数据库也是可以顶住压力,无非就是对数据库产生周期性的压力,而缓存服。务节点的宕机,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮了
解决方案:
Redis高可用: 这个思想的含义是:既然Redis可能挂掉,那么就多设置几台Redis,这样一台挂掉之后其他的还可以继续工作,也就是搭建一个集群。
限流降级: 在缓存失效后通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
数据预热: 在正式部署之前,先把可能发生高并发的数据先访问一遍,这样可能大量的数据就会加载到缓存中,在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
Redis支持的数据类型有哪些?
Redis 支持的数类型: string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。
Redis 支持java客户端都有哪些?
支持java客户端有:Redisson、Jedis、lettuce等。
Jedis和Redisson有哪些区别?
jedis:提供了比较全面的Redis命令的支持。
Redisson:实现了分布式和可拓展的java数据结构,与jedis相比Redisson的功能相对简单,不支持排序、事务、管道、分区等Redis特性。
怎么保证缓存和数据数据的一致性?
- 合理设置缓存的过期时间;
- 新增、更改、删除数据库操作时同步更新Redis,可以使用事务机制来保证数据的一致性。
Redis持久化有几种方式?
- Redis的持久化两种方式:
RDB(Redis Database)
在指定的时间间隔将内存中的数据集快照写入磁盘,也就是Snopshot快照,它恢复时是将快照文件直接读到内存里。
Redis会单个创建一个子进程来进行持久化,会先把数据写到一个临时文件中,待持久化过程结束后,再用这个临时文件来替换啥歌词持久化好的文件,整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能,如果需要进行大规模的数据恢复,且对数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点就是 最后一次持久化的数据可能丢失。默认的是RDB,一把情况不需要在修改这个配置。
RDB保存的文件是 dump.db
触发机制
save的规则满足的情况下,会自动触发rdb规则。
执行flushall命令,也会发出rdb规则。
退出redis也会产生rdb文件。
备份就会自动生成一个dump.rdb文件。
如何恢复rdb文件
只需要将rdb文件放在redis目录中就可以,redis启动的时候会自动检查dump.rdb 恢复其中的数据。
优点:
1、适合大规模的数据恢复;
2、对数据的完整性不高。
缺点:
1、需要一定的数据进程操作,如个人redis意外宕机,这个最后一次修改的数据就会没有了。
2、fork进程的时候,会占用一定的内容空间。
AOF(Append Only File)
- 以日志的形式来记录每一个命令的操作,讲Redis执行过程的所有命令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,Redis重启时候就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
工作原理:
1、写操作记录:
当Redis接收到写操作(SET、DEL、LPUSH等命令)时,这些操作会追加到AOF文件中,而不是直接修改内存中的数据。 AOF文件记录了Redis执行的所有操作命令,这样Redis重启的时候就可以重新执行这些命令来恢复数据。
2、文件格式:
AOF的格式是简单的文本格式,每一行记录一个写操作命令。Redis会根据命令的实际参数,将其格式化为可执行的Redis命令 并写入到AOF文件中。
3、持久化策略:
每秒写入:Redis会每秒将写操作追加到AOF文件中,这是一种常见的设置,兼顾了性能和持久化的可能性。
每次写入:每个写操作强制将AOF文件同步到磁盘,这种设置可能提供更高的数据安,但会显著影响性能。
从不写入:Redsi依赖操作系统的文件系统缓存来处理 AOF文件的写入,性能最佳,但可能会导致更多的数据丢失。
4、重写:随着时间的推移,AOF文件会不断增长,因为每个操作都会被追加到文件中,为了避免AOF文件无限制的增长,Redis提供了AOF重写机制。AOF重写通过创建一个新的AOF文件,该文件仅包含当前数据库状态的最小命令集合,从而又换 AOF文件的大小。
这个过程不会中断Redis服务,新的AOF文件会在后台创建,并在创建完成后替换旧的AOF文件。
数据恢复:
当Redis重启的时候,它会加载AOF文件,并顺序执行其中的命令以恢复数据,这种方式保证了即使Redis崩溃,最新的写操作也能通过AOF文件得到恢复。
aof保存的是appendonly.aof文件
如果aof文件被损坏,redis是无法启动的,我们需要借助redis提供的 ‘ redis-check-aof --fix ’工具可以自动修复aof文件,aof默认就是无限追加。
优点:
更高的数据持久化:
AOF持久化能提供比RDB更高的数据持久性,因为它记录了所有写操作,可以实现接近实时的数据恢复。
更好的数据恢复能力:由于记录了详细的写操作日志,AOF能够恢复到非常接近崩溃的数据状态。
缺点:
文件体积较大:由于AOF记录了所有写的操作,它的文件体积通常比RDB快照大。
性能开销:频繁的写操作和同步可能会带来性能开销,尤其是在appendsync always设置下。
重写操作:尽管AOF重写可以减小文件大小,但在重写过程中也会带来一定的性能开销。
什么是哨兵模式?
主从切换技术的方法是:当主从服务器宕机后,需要手动把一台服务器切换为主服务器,这就是人工干预,费时费力,还会造成一段时间服务不可用,这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式,Redis2.8版本开始提供了Sentinel(哨兵)模式来解决这个问题。
形象点就是 谋朝篡位的自动版,能够监控主机是否故障,如果故障了 哨兵之间就会开始进行自动投票,根据投票数自动将从库转为主库
,它会独立运行,其原理就是 哨兵通过发送命令,等待Redis服务器响应,从而监控运行多个Redis实例。
这里的哨兵有两个作用:
- 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
- 当哨兵检测到master宕机,会自动将slave切换成master,然后通过 发布订阅 ,通过其他的从服务器,修改配置文件,让它们切换主机。
然而一个哨兵进程对Redis服务器进程进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行相互监控,这样就形成了多哨兵模式。
假设服务器宕机,哨兵1 先检测到这个结果,系统并不会马上进行 failover 过程,仅仅是哨兵 1 主管的认为主服务器不可用,这个现象成为主管下线,当后面的哨兵也检测到服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行 failover【故障转移】操作,切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。
在6381这个服务器可以查询到也就变成了主服务器
从哨兵日志里面可以看到:
如果master节点断开,这个时候就会从 从机中随机选择一个服务器(这里面有一个投票算法),如果以前的主机回来,只能重新归并到新的主机下,这就是哨兵模式。
优点:
1、哨兵集群,基于主从复制模式,所有的主从配置优点它都具备。
2、主从可以切换,故障可以转移,系统的可用性就会更好
3、哨兵模式就是主从模式的升级,手动变自动,更加健壮。
缺点:
1、Redis不好在线扩容,集群容量一旦达到上线,在线扩容就会十分麻烦
2、实现哨兵模式的配置是很麻烦的,里面有很多的选择
哨兵模式的全部配置:
邮件的shell编程:
今天的分享就到这里啦,感谢大家的阅览,小江会一直与大家一起努力,文章中如有不足之处,你的支持是我前进的最大动力,请多多指教,感谢支持,持续更新中 ……