18 道 Redis 面试题

学习是一条漫长之路

  • 什么是Redis?
    Redis 全称 Remote Dictionary Server 远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持续化的日志型、Key-Value 数据库,并提供多种语言的API。
  • Redis 相比 memcached 有哪些优势?
    1. memcached 所有的值均是简单的字符串,redis 作为其代替者,支持更为丰富的数据类型。
    2. redis 的速度比 memcached 快得多。
    3. redi 可以支持持久化数据
  • Redis 支持几种数据类型?以及每种数据类型的使用场景?
    1. String 字符串——这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。
    2. Hash 哈希——这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。
    3. List 列表——使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。
    4. Set 集合——因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。
    5. sorted set 有序集合——sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。
  • Redis 主要消耗什么物理资源?
    内存
  • Redis 有哪几种数据淘汰策略?
    1. volatile-lru:从设置了过期时间的数据集中,选择最近最久未使用的数据释放。
    2. allkeys-lru:从数据集中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放。
    3. volatile-random:从设置了过期时间的数据集中,随机选择一个数据进行释放。
    4. allkeys-random:从数据集中(包括了设置过期时间以及为设置过期时间)随机选择一个数据进行释放。
    5. volatile-ttl:从设置了过期时间的数据集中,选择马上就要过期的数据进行释放操作。
    6. noevication:不删除任意数据(但 redis 还会根据引用计数器进行释放),这时如果内存不够,会直接返回错误。
  • Redis 集群方案应该怎么做?都有那些方案?
    1. 客户端分片
    2. 基于代理的分片
    3. 路由查询
  • Redis 有哪些适合的场景?
    1. 会话缓存 (Session Cache)
    2. 全页缓存(FPC)
    3. 队列
    4. 排行榜、计数器
    5. 发布、订阅
  • Redis 支持的Java客户端都有哪些?官方推荐使用哪个?
    Redisson、Jedis、lettuce等等,官方推荐使用 Redisson
  • 你知道有哪些 Redis 分区实现方案?
    1. 客户端分区
      就是由客户端自己决定要将 key 存放在哪个实例,再去哪个实力获取
    2. 代理分区
      客户端依赖一个代理,代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些 Redis 实例,然后根据 Redis 的响应结果返回给客户端。Redis 和 memcached 的一种代理实现就是 Twemproxy
    3. 查询路由
      客户端随机的请求任意一个 redis 实例,然后由 Redis 将请求转发给正确的 Redis 节点
  • Redis 分区有什么缺点?
    多键操作是不被支持的
    当应用分区的时候,数据的处理非常复杂
    分区的最小粒度是键,因此我们不能将关联到一个键的很大的数据集映射到不同的实例
  • 分布式 Redis 是前期做还是后期规模上来了再做好?为什么?
    为防止以后的扩容,最好的办法就是一开始就启动较多实例。
  • Redis 与其他 key-value 存储有什么不同?
    • Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径,Redis 的数据类型都是基于基本数据结构的同时对程序眼透明,无需进行额外的抽象。
    • Redis 运行在内存中但是可以不用持久化到磁盘,所以在对不用数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存,在内存数据库方面的另一个有点是:相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis 可以做很多内部复杂性很强的事情,同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
  • Redis 常见性能问题和解决方案?
    1. Master 最好不要做任何持久化工作,如 RDB 内存快照和 AOF 日志文件
    2. 如果数据比较重要,某个 Slave 开启AOF 备份数据,策略设置为每秒同步一次
    3. 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
    4. 尽量避免在压力很大的主库上增加从库
    5. 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master < Slave1 < Slave2 < Slave3 … 这样的结构方便解决单点故障问题,实现 Slave 对 Master 的替换,如果 Master 挂了,可以立刻启动 Slave1 做 Master ,其他不变。
  • 修改配置不重启 Redis 会实时生效吗?
    一般不需要重启。
  • 单线程的 redis 为什么这么快?
    1. 纯内存操作
    2. 单线程操作,避免了频繁的上下文切换
    3. 采用了非阻塞 I/O 多路复用机制
  • 为什么 Redis 的操作是原子性的,怎么保证原子性的?
    1. 对于 Redis 而言,命令的原子性指的是:一个操作的不可再分,操作要么执行,要么不执行。
    2. Redis 的操作之所以是原子性的,是因为 Redis 是单线程的。
    3. Redis 本身提供的所有 API 都是原子操作,Redis 中的事务其实是要保证批量操作的原子性。
    4. 多个命令在并发中也是原子性的吗?不一定,将get和set改为单命令操作,incr,使用Redis 的事务,或者使用 Redis + Lua 的方式实现。
  • 讲讲Redis 事务
    Redis 事务功能通过MULTI、EXEC、DISCARD和WATCH 四个原语实现的。Redis 会将一个事务中的所有命令序列化,然后按照顺序执行。
    1. redis 不支持回滚,“Redis 在事务失败时不进行回滚,而是继续执行余下的命令”,所以 Redis 的内部可以保持简单且快速。
    2. 如果在一个事务中的命令出现错误,那么所有的命令都不会执行。
    3. 如果在一个事务中出现运行错误,那么正确的命令会被i执行。
  1. MULTI命令用于开启一个事务,它总是返回OK,MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当 EXEC命令被调用时,所有队列中的命令才会被执行。
  2. EXEC:执行所有事务快内的命令,返回事务块的所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 null。
  3. 通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务,并且客户端会从事务状态中退出。
  4. WATCH命令可以为 Redis 事务提供 check-and set (CAS)行为,可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。
  • Redis 实现分布式锁?
    Redis 为单进程单线程模式,采用队列模式将并发访问变为串行访问,且多客户端对 Redis 的连接并不存在竞争关系 Redis 中可以使用 SETN 命令实现分布式锁。
    将 key 的值设为 value ,当且仅当 key 不存在,若给定的 key 已经存在,则 SETNX 不做任何动作
    解锁:使用 del key 命令就能释放锁
    解决死锁:
    1. 通过 Redis 中 expire() 给锁设定最大持有时间,如果超时,则 Redis 来帮我们释放锁。
    2. 使用 setnx key “当前系统时间+锁持有时间” 和 getset key “当前系统时间+锁持有时间” 组合的命令就可以实现。
发布了24 篇原创文章 · 获赞 47 · 访问量 4078

猜你喜欢

转载自blog.csdn.net/qq_43647359/article/details/104767563