Redis面试题

Redis的key和value可以存储的最大值分别是多少

虽然Key的大小上限为512M,但是一般建议key的大小不要超过1KB,这样既可以节约存储空间,又有利于Redis进行检索,value的最大值也是512M,对于String类型的value值上限为512M,而集合、链表、哈希等key类型
单个元素的value上限也为512M。

Redis的主从模式,一主两从有几种方式,有什么优缺点

  1. 一个master下挂两个slave,优点是slave同步速度快,缺点是master压力大
  2. 一个master下挂一个slave,这个slave下再挂一个slave,优点是master压力小,缺点是后者slave同步速度慢

Redis的哨兵模式,当master挂了之后,是怎么从剩余的slave中选择新的master的

  1. 先比较优先级,默认为100,数字越小优先级越高,越容易成为master
  2. 再比较数据的新旧程度
  3. 比较id

Redis的集群模式的优缺点

  1. 方便扩容和缩容
  2. 方便快速定位,插入时是哪个槽,查询时就是哪个槽
  3. 有可能丢数据,某个master节点没来得及同步数据给slave时,master节点挂掉了

如何用Redis来实现一个抽奖程序,你会怎么实现?

  1. 利用set
  2. sadd添加uid进set
  3. smembers查看所有uid,
  4. randmember从set随机选一个uid(可以指定选1个,还是选3个),不会删除uid
  5. spop也有随机的效果,但是会删除uid

Redis有哪些数据结构?分别有哪些典型的应用场景?

Redis的数据结构有:

  1. 字符串:可以用来做最简单的数据,可以缓存某个简单的字符串,也可以缓存某个json格式的字符串,Redis分布式锁的实现就利用了这种数据结构,还包括可以实现计数器、分布式ID
  2. 哈希表:可以用来存储一些key-value对,更适合用来存储对象
  3. 列表:Redis的列表通过命令的组合,既可以当做栈,也可以当做队列来使用,可以用来缓存类似微信公众号、微博等消息流数据
  4. 集合:和列表类似,也可以存储多个元素,但是不能重复,集合可以进行交集、并集、差集操作,从而可以实现类似,我和某人共同关注的人、朋友圈点赞等功能
  5. 有序集合:集合是无序的,有序集合可以设置顺序,可以用来实现排行榜功能

Redis分布式锁底层是如何实现的?

  1. 首先利用setnx来保证:如果key不存在才能获取到锁,如果key存在,则获取不到锁
  2. 然后还要利用lua脚本来保证多个redis操作的原子性
  3. 同时还要考虑到锁过期,所以需要额外的一个看门狗定时任务来监听锁是否需要续约
  4. 同时还要考虑到redis节点挂掉后的情况,所以需要采用红锁的方式来同时向N/2+1个节点申请锁,都申请到了才证明获取锁成功,这样就算其中某个redis节点挂掉了,锁也不能被其他客户端获取到

Redis主从复制的核心原理

全量同步:

  1. 一般发生在从节点初始化的时候
  2. 从节点发送SYNC命令连接主节点
  3. 主节点接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件,并使用缓冲区replication buffer记录在这个过程中接收到的写命令
  4. 主节点BGSAVE命令执行完后,向所有从节点发送RDB文件,并在发送缓冲区replication buffer记录的写命令
  5. 从节点收到RDB文件后丢弃所有旧数据,载入收到的RDB文件中的数据
  6. 主节点RDB文件发送完毕后,开始向从节点发送缓冲区replication buffer中的写命令
  7. 从节点完成RDB的载入后,开始接收客户端命令,并执行来自主节点缓冲区replication buffer的写命令

增量同步
Redis主节点每执行一个写命令就会向从节点异步发送相同的写命令,从节点接收并执行收到的写命令

缓存穿透、缓存击穿、缓存雪崩分别是什么

缓存中存放的大多都是热点数据,目的就是防止请求可以直接从缓存中获取到数据,而不用访问Mysql。

  1. 缓存雪崩:如果缓存中某一时刻大批热点数据同时过期,那么就可能导致大量请求直接访问Mysql了,解决办法就是在过期时间上增加一点随机值,另外如果搭建一个高可用的Redis集群也是防止缓存雪崩的有效手段
  2. 缓存击穿:和缓存雪崩类似,缓存雪崩是大批热点数据失效,而缓存击穿是指某一个热点key突然失效,也导致了大量请求直接访问Mysql数据库,这就是缓存击穿,解决方案就是考虑这个热点key不设过期时间
  3. 缓存穿透:假如某一时刻访问redis的大量key都在redis中不存在(比如黑客故意伪造一些乱七八糟的key),那么也会给数据造成压力,这就是缓存穿透,解决方案是使用布隆过滤器,它的作用就是如果它认为一个key不存在,那么这个key就肯定不存在,所以可以在缓存之前加一层布隆过滤器来拦截不存在的key

Redis和Mysql如何保证数据一致

  1. 先更新Mysql,再更新Redis,如果更新Redis失败,可能仍然不一致
  2. 先删除Redis缓存数据,再更新Mysql,再次查询的时候在将数据添加到缓存中,这种方案能解决1方案的问题,但是在高并发下性能较低,而且仍然会出现数据不一致的问题,比如线程1删除了Redis缓存数据,正在更新Mysql,此时另外一个查询再查询,那么就会把Mysql中老数据又查到Redis中
  3. 延时双删,步骤是:先删除Redis缓存数据,再更新Mysql,延迟几百毫秒再删除Redis缓存数据,这样就算在更新Mysql时,有其他线程读了Mysql,把老数据读到了Redis中,那么也会被删除掉,从而把数据保持一致

1、什么是redis?

redis是一个内存数据库,数据的读写操作都在内存中进行,因此速度非常快,常用于缓存,消息队列,分布式锁等场景。

2、Redis 和 Memcached 有什么区别?

首先两者都是内存数据库,性能非常高,但是redis 有更丰富的数据结构,数据可以持久化,支持集群,还有发布订阅、lua脚本、事务等功能,因此使用redis更多一点。

3、为什么用 Redis 作为 MySQL 的缓存?

redis兼具高性能、高并发两大特性,高性能是因为redis对于数据的读写操作都是在内存中进行的,因此性能非常高,高并发是指redis的单机吞吐率是10w,大约是mysql的10倍左右。

4、Redis 数据类型以及使用场景分别是什么?

String,主要用于缓存对象等;

list,主要用于消息队列,但是存在着生产者无法自动生成全局唯一ID,无法以消费组形式消费等问题;

hash,主要用于缓存对象等;

set,主要用于聚合计算,例如点赞,共同关注等;

zset,主要用于排行榜,电话,姓名排序等;

bitmap,主要用于记录签到情况,判断登录状态等;

hyperloglog,主要用于百万的数据统计等;

geo,主要用于存储位置;

stream,主要用于消息队列,相对于list,能解决list存在的问题。

5、五种常见的 Redis 数据类型是怎么实现?

String:sds

list:quicklist

hash:listpack 和 哈希表

set:哈希表和整数集合

zset:listpack 和 跳表

6、listpack是什么?

listpack也叫紧凑列表,是用一块连续的内存空间来保存数据,为了节省内存空间,还使用多种编码方式来表示不同长度的数据。

7、Redis 是单线程吗?

不是单线程,redis的单线程是指接收请求,解析请求,处理请求内容,返回结果这个过程是单线程的,但是redis还会在后台创建关闭文件,aof刷盘,释放内存的线程,主要也是因为这些操作比较费时。

8、Redis 单线程模式是怎样的?

当有多个客户端链接时,会采用IO多路复用,epoll wait会发现事件然后分发给事件处理器,然后通过连接事件处理函数、读事件处理函数、写事件处理函数分别进行处理,连接事件处理函数会调用accept接收连接,然后将已连接的socket添加到epoll中,并注册读事件处理函数或写事件处理函数,读事件处理函数会调用read接收数据,写事件处理函数会调用write发送数据。写事件处理函数会将准备好的的数据发送到队列中,读事件处理函数,也会在数据准备完成后添加到发送队列,然后同时将执行结果加入到缓存中。

9、Redis 采用单线程为什么还这么快?

redis 的大部分操作都在内存中完成,并采用了高效的数据结构;redis是单线程的,避免线程之间的竞争;redis采用了IO多路复用机制处理大量的客户端socket请求,因此速度比较快。

10、Redis 6.0 之前为什么使用单线程?Redis 6.0 之后为什么引入了多线程?

因为制约redis性能的一直不是cpu,因此单线程就足够,6.0之后考虑到redis的性能瓶颈受限于网络IO,因此引入多个IO线程处理网络请求,但对任务的处理过程仍然是单线程。

11、Redis 如何实现数据不丢失?

一共有三种方式, 第一种是RDB,其是将写命令以追加写的方式写入到文件中,第二种是RDB,它是将某一个时刻的数据以二进制的形式写入到磁盘,第三种是混合存储模式,集成了RDB和AOF的优点,是4.0新增的方式。

12、AOF 日志过大,会触发什么机制?

当写操作命令越来越多时,会导致AOF日志过大,此时会触发重写机制,缩小AOF日志的大小,举个例子:对同一个key值的两次value更新,只会保存最后一个。

13、重写 AOF 日志的过程是怎样的?

为了减少对于主线程的阻塞,这个过程通常是由子线程来完成的,为了保证主线程和子线程的内存数据的一致性,在子线程重写的过程时,会同时将数据发送到AOF缓冲区和AOF重写缓冲区,然后当子线程重写完成后,会给主线程发送指令,此时主线程会有两个操作,第一个操作是读取重写缓冲区的内容,将其加入到AOF文件中,第二个操作是将新的AOF文件覆盖原来的AOF文件,从而实现主线程和子线程的数据一致。

14、RDB 快照是如何实现的呢?

AOF日志是记录操作指令,因此当redis故障恢复时,一旦AOF文件过大,就会导致恢复缓慢,那么RDB就登场了,RDB是存储某一时刻的数据的二进制文件,这也当恢复时,采用RDB的效率会更高一点,直接将RDB文件读入内存即可。

15、RDB 在执行快照的时候,数据能修改吗?

可以的,关键在于写时复制技术,但此时RDB出来的数据就不是最新的数据了,只能当下一次快照时,才能读取到最新的数据。

16、为什么会有混合持久化?

RDB的优点在于恢复数据很快,但缺点在于快照的间隔很难保证,太快会导致对性能的负荷较大,太慢又会导致数据的缺失较多。

AOF的优点在于数据的缺失较少,但恢复数据的过程较慢。

因此为了结合二者的优点,在进行AOF日志重写的过程时,前半段会通过RDB的方式,后半段追加写入的内容采用AOF的方式,因此新的AOF日志前半段是RDB的格式,后半段是AOF的格式,优点就是让redis能更快的启动,但是缺点是让AOF的文件可读性变得较差。

17、Redis 如何实现服务高可用?

①主从复制,同时主节点进行写操作或读操作,从节点只进行读操作,读写分离。

②哨兵模式,为了避免主从复制出现问题手动恢复的情况出现,通过哨兵模式监控主从节点的工作情况,并进行故障转移。

③切片集群,当单机存储的缓存数据太大时,可以采用切片集群的方式将数据分散到多台机器上,从而避免对单机的负荷太大,提高读写性能。

18、集群脑裂导致数据丢失怎么办?

脑裂是指当主从断开后,由于只是网络问题,客户端认为当前主还未下线,故还在向主发送数据,但由于网络问题,这些数据都无法同步给从节点,这时哨兵发现主出问题,故将其中一个从升为新主,而主则降为从,此时进行全量同步时,就会导致旧主的缓冲区的数据全部丢失。

解决方法:通过设置参数,如延迟的时间和从连接的数目等,进而可以限制当主心跳监测不到时,禁止向原旧主发送数据,并且只将数据写到新主上。

19、Redis 使用的过期删除策略是什么?

惰性删除+定期删除策略。

惰性删除:不主动检测过期的key,只要当要使用时,发现其过期,旧删除该key

定时删除:按照一定的时间间隔删除过期key

定期删除:每隔一定时间,随机选取20个key检测是否过期,如果超过其1/4过期,则重新选择20个key进行检测,如果不超过1/4,则结束该过程

使用惰性删除+定期删除策略也是为了平衡cpu的使用以及对于内存的浪费。

20、Redis 内存满了,会发生什么?

当redis运行内存达到某一个阈值时,就会触发内存淘汰机制,一共有八种。

①不进行数据淘汰

②随机淘汰过期的键值

③优先淘汰更早过期的键值

④优先淘汰最久未被使用的设置了过期时间的键值

⑤优先淘汰最少使用的设置了过期时间的键值

⑥随机淘汰任意键值

⑦优先淘汰最久未被使用的键值

⑧优先淘汰最少使用的键值

21、LRU 算法和 LFU 算法有什么区别?

LRU是指淘汰最近最少使用的数据(时间)

LFU是指淘汰最近最少次数使用的数据(次数)

LRU是通过链表实现的,LFU是通过在结构体中增加数据的访问频次信息来实现的。

22、了解缓存雪崩、缓存击穿、缓存穿透吗?

缓存穿透是指该数据都不存在于数据库和缓存中,避免缓存穿透的方法主要有设置布隆过滤,或者缓存空对象来解决。

缓存击穿是指某热点数据过期,此时大量的请求打到数据库上,给数据库造成了巨大的压力,解决方法主要有互斥锁和逻辑过期,逻辑过期的一致性较差。

缓存雪崩主要是指大量的key同时失效造成的访问压力过大,解决方法主要有给不同的key随机设置过期时间,若是redis宕机引发的,可以设置集群或者增加多级缓存策略来解决。

23、如何保证数据库和缓存的数据一致性?

先更新数据库,再删除缓存。(也会出现数据不一致的情况,但由于更新缓存的速度远远快于写入数据库的速度,故出现的概率很低) 解决方案:可以通过加分布式锁或者加入较短的过期时间来保证

先删除缓存,再更新数据库。 会有极大可能发生数据不一致的情况,解决方案:延迟双删

24、redis的大key如何处理?

大key指的是key 所对应的value很大,它的危害主要有:会造成内存分布不均,会造成客户端超时阻塞,从客户端反应就是迟迟未能响应,可以通过scan命令或一些工具查找大key,解决方案可以通过分批次删除或异步删除来解决。

25、redis的管道有什么用?

可以解决多个命令执行时的网络等待

26、为什么redis不支持事务回滚?

设计理念主要是简单高效,支持事务回滚这种功能与设计理念相悖,其次发生错误主要是编程错误,主要是在开发阶段,生产环境中很少会出现,因此没必要设计这个功能。

27、如何使用redis实现分布式锁?

使用set nx ex 指令,优点在于性能高效,实现简单, 但是缺点在于超时时间不好设置,以及在集群模式下,很容易出现给主加锁,但是没同步到其他节点,就宕机了,仍然还能给新主加锁,就是所谓的分布式锁不可靠,因此在集群模式下,我们可以设置,当主节点和半数以上的从节点加锁成功才认为分布式锁加锁成功,否则就认为失败,回滚之前加锁成功的节点。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、什么是 Redis? 2、Redis 相比 memcached 有哪些优势? 3、Redis 支持哪几种数据类型? 4、Redis 主要消耗什么物理资源? 5、Redis 的全称是什么? 6、Redis 有哪几种数据淘汰策略? 7、Redis 官方为什么不提供 Windows 版本? 8、一个字符串类型的值能存储最大容量是多少? 9、为什么 Redis 需要把所有数据放到内存中? 10、Redis 集群方案应该怎么做?都有哪些方案? 11、Redis 集群方案什么情况下会导致整个集群不可用? 12、MySQL 里有 2000w 数据,Redis 中只存 20w 的数据, 如何保证 Redis 中的数据都是热点数据? 13、Redis 有哪些适合的场景? 14、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个? 15、RedisRedisson 有什么关系? 16、Jedis 与 Redisson 对比有什么优缺点? 17、Redis 如何设置密码及验证密码? 18、说说 Redis 哈希槽的概念? 19、Redis 集群的主从复制模型是怎样的? 20、Redis 集群会有写操作丢失吗?为什么? 21、Redis 集群之间是如何复制的? 22、Redis 集群最大节点个数是多少? 23、Redis 集群如何选择数据库? 24、怎么测试 Redis 的连通性? 25、Redis 中的管道有什么用? 26、怎么理解 Redis 事务? 27、Redis 事务相关的命令有哪几个? 28、Redis key 的过期时间和永久有效分别怎么设置? 29、Redis 如何做内存优化? 30、Redis 回收进程如何工作的? 31、Redis 回收使用的是什么算法? 32、Redis 如何做大量数据插入? 33、为什么要做 Redis 分区? 34、你知道有哪些 Redis 分区实现方案? 35、Redis 分区有什么缺点? 36、Redis 持久化数据和缓存怎么做扩容? 37、分布式 Redis 是前期做还是后期规模上来了再做好?为 什么? 38、Twemproxy 是什么? 39、支持一致性哈希的客户端有哪些? 40、Redis 与其他 key-value 存储有什么不同? 41、Redis 的内存占用情况怎么样? 42、都有哪些办法可以降低 Redis 的内存使用情况呢? 43、查看 Redis 使用情况及状态信息用什么命令? 44、Redis 的内存用完了会发生什么? 45、Redis 是单线程的,如何提高多核 CPU 的利用率? 46、一个 Redis 实例最多能存放多少的 keys?List、Set、 Sorted Set 他们最多能存放多少元素? 47、Redis 常见性能问题和解决方案? 48、Redis 提供了哪几种持久化方式? 49、如何选择合适的持久化方式? 50、修改配置不重启 Redis 会实时生效吗?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值