Redis 面试题汇总1.Redis 使用场景有哪些?
答:Redis 使用场景如下:
- 记录帖子的点赞数、点击数和评论数
- 缓存最近的热帖
- 缓存文章细节
- 记录用户会话信息
答:Redis 功能如下:
- 数据缓存功能
- 分布式锁的功能
- 支持数据持久化
- 支持事务
- 支持新闻队列
答:Redis 支持的数据类型如下:
- String 字符串
- List 列表
- Set 无序集合
- ZSet 有序集合
- Hash 哈希类型
答:Redis 相比 Memcached 优势如下:
- Memcached 所有的值都是简单的字符串,Redis 支持更丰富的数据类型
- Redis 的速度比 Memcached 要快
- Redis 可以持久化
- Redis 过期时间可设置
- Redis 支持主从同步
答:Redis 淘汰策略如下:
- noeviction:禁止淘汰数据;
- allkeys-lru:尽量回收最少使用的键,使新添加的数据有空间存储;
- volatile-lru:尽量回收最少使用的键,但仅限于过期集合的键,使新添加的数据有空间存储;
- allkeys-random:回收随机键使新添加的数据有空间存储;
- volatile-random:回收随机键使新添加的数据有空间存储,但仅限于过期集合键;
- volatile-ttl:回收过期集合的键,优先回收存活时间短的键,使新添加的数据有空间存储。
答:Redis 官员不支持 Windows 因为现在,版本 Linux 如果开发的话,版本已经相当稳定了 Windows 相反,版本会带来兼容性等问题。
7.为什么 Redis 是单线程吗?答:因为 Redis 瓶颈最有可能是机器内存或网络带宽,而不是单线程,因为单线程不是 Redis 性能瓶颈,单线程更容易实现,因此 Redis 选择使用单线程来实现。
例如,单线程并不意味着运行速度慢,Nginx 和 NodeJs 它们都是单线程高性能的代表。
8.为什么 Redis 所有数据都需要放在内存中吗?答:Redis 为了达到最快的读写速度,在内存中读取所有数据,并通过异步将数据写入磁盘,以便 Redis 它具有快速查询和数据持久化的特点。
9.在 Redis 中 key 最大容量是多少?答:最大容量 512 MB,官方说明如下图所示:
10.Jedis 和 Redisson 有什么区别?答:Jedis 和 Redisson 区别如下:
- Jedis 是 Redis 的 Java 实现客户端,它 API 提供更全面的服务 Redis 支持命令;
- Redisson 实现了分布式和可扩展性 Java 数据结构,和 Jedis 相比之下,功能相对简单,不支持字符串操作、排序、事务、管道、分区等 Redis 特性。Redisson 目的是促进用户对 Redis 关注分离,使用户能够更集中精力处理业务逻辑。
答:Redis 通过 expire() 方法设置过期时间,语法:redis.expire(key, expiration)。当 expire 过期时间设定为 -1 时间表示永远不会过期。
12.如何保证 Redis 数据一致性?答:可以使用以下方法来保证 Redis 数据一致性:
- 合理设置缓存过期时间;
- 同步更新、更改和删除数据库操作 Redis,事物机制可以用来保证数据的一致性。
答:Redis 数据结构是跳跃表,跳跃表是一种基于链表的扩展,跳跃表或链表,是一个有序的链表,基于比较,但普通链表只能通过,跳跃表增加了层的概念,层次越高,元素越少,每次从高层搜索,直到找到合适的位置,从图中可以看到高节点远低于底节点,从而实现跳跃搜索。
跳跃表的优点:
- 比红黑树更容易实现
- 比红黑树更容易扩展
- 为了平衡高度,红黑树需要旋转附近的节点,高并发需要锁定,跳跃表不需要考虑
跳跃表的缺点:
- 每个节点的大小取决于节点的层数,因为它比红黑树占用的内存更多
- 局部空间差导致缓存命中率低,比红黑树慢一点
答:首先,红黑树的存储比较复杂,调整涉及多个节点的并发修改;第二,离根节点越近,竞争就越容易。即使是不同叶节点的操作也可能由于平衡操作而逐步向上涉及接近根节点,跳跃表也可以使用 CAS(Compare And Swap)并发操作节点,更容易实现,更局部化。
15.缓存穿透是什么?如何解决?答:缓存穿透是指查询一个不存在的数据。因为缓存中没有,所以每次都需要从数据库中查询,但是数据库中没有相应的数据,所以不会写入缓存,会导致每个请求都去数据库查询。这种行为叫做缓存穿透。
解决方案是缓存数据库是否有数据,但将没有数据的缓存结果的过期时间设置为相对较短的值,如 3 分钟。
16.什么是缓存雪崩,如何解决?答:指缓存因某些原因,如停机或缓存过期,导致大量请求到达后端数据库,导致数据库崩溃。
缓存雪崩的解决方案如下:
- 分析业务功能,尽量均匀分布缓存失效时间点;
- 使用 Redis 保证缓存系统的高可用性。
答:缓存预热是指系统启动后,直接将相关缓存数据加载到缓存系统中,避免用户请求时查询数据库,然后缓存数据的问题。
缓存预热的实现方法可分为以下两种:
- 当数据量不大时,在项目启动时进行加载缓存;
- 当数据量较大时,设置定时任务脚本,以刷新缓存。
答:在 Java 可在程序中使用 Jedis 来操作 Redis,使用步骤如下:
1)添加 Jedis 引用
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>x.x.x</version></dependency>
2)连接和操作 Redis
Jedis jedis = new Jedis("127.0.0.1",6379);// 存值jedis.set("hello","world");// 取值jedis.get("hello");// 关闭连接jedis.close();
19.什么是 Redis 持久性?如何进行? Redis 持久化?
答:Redis 持久性是指将内存中的数据保存在磁盘中,重启时可重新加载使用。 Redis 有以下两种持久方案:
- RDB(Redis DataBase):是指在制定时间间隔内将内存中的数据集快照写入磁盘;
- AOF(Append Only File):该机制将以日志的形式记录服务器处理的每个写作操作 Redis 在服务器启动之初,将读取文件重建数据库,以确保启动后数据库中的数据完整。
Redis 默认支持的持久化方式是 RDB 方式。
20.RDB 和 AOF 有什么区别?答:RDB 和 AOF 区别如下:
- RDB 可能会导致一定程度的数据丢失,AOF 不会造成数据丢失
- RDB 启动效率更高
- AOF 占用的空间比 RDB 大,AOF 同步速度比 RDB 慢
一般来说,如果对数据的完整性要求不高,RDB 这是最好的解决方案,反之亦然 AOF。
21.Redis 监控工具有哪些?答:常用的 Redis 监控工具如下:
- Redis-stat:采用 Ruby 开发,基于 Redis 的 info 不影响命令统计 Redis 的性能;
- RedisLive:采用 Python 通过监控脚本开发的可视化和查询分析工具 Redis 提供的 MONITOR 命令从被监控 Redis 在实例中获取数据并存储到 Redis 在监控实例中。
答:使用 slowlog get 定位慢查询操作,如下所示:
127.0.0.1:6379> slowlog get
- (integer) 0
- (integer) 1565937939
- (integer) 28003
- "lpush"
2) "list" 3) "1" 4) "2" 5) "6" 6) "3" 7) "4" 8) "9" 9) "8"
其中:
- 表示慢查询记录 id
- 表示发起命令的时间戳
- 表示命令耗时,单位为微秒
- 表示本条记录的命令和参数
答:SAVE 和 BGSAVE 都是用于 Redis 它们的区别如下:
- SAVE 直接调用 rdbSave 函数(用于 Redis 持久函数),阻塞 Redis 在主流程堵塞期间,服务器无法处理客户端的任何请求,直至保存完成;
- BGSAVE 将创建一个子过程,负责调用子过程 rdbSave 保存完成后,函数将完成信号发送到主过程,Redis 服务器在 BGSAVE 客户端的请求在执行期间仍可继续处理。
答:Redis 主从同步和从从同步可以实现。主节点在第一次同步时做一次 BGSAVE,同时,将后续修改操作记录在内存中,完成后将记录在内存中 RDB 文件完全同步到复制节点,接受复制节点后将完成 RDB 将镜像加载到内存中,然后通知主节点将修改后的操作记录同步到复制节点进行重放,以完成同步过程。
25.Redis 可以切换数据库吗?如何切换?答:Redis 不像 MySQL 数据库的概念与其他关系数据库相同,不同的数据存在于不同的数据库中,Redis 数据库由整数索引标记,而不是数据库名称。默认情况下,客户端连接到数据库 0.数据库总数可以在配置文件中控制,默认为 16 个。
可以使用 select index 切换数据库如下所示:
26.Redis 集群策略有哪些?127.0.0.1:6379> select 0
OK
答:Redis 集群策略如下 3 种:
- 主从策略:1 另外,台机作为写作操作, 2 平台作为读取操作类似于 MySQL 主从方式;
- 哨兵策略:增加 1 台机作为哨兵进行监控 3 主机从机器,当主节点挂断时,机器内部选举,从集群中指定机器升级为主节点,实现高可用性。当主节点恢复时,从节点中添加并继续提供服务;
- 集群策略:Redis 3.0 然后增加了集群的概念,可以实现多主多从的结构,实现真正的高可用性。
答:Redis 集群实现方案如下:
- Twemproxy 是 Twitter 开源的 Redis 代理,它的使用和普通 Redis 完全一致,作为代理接收请求并使用它 hash 算法将请求转移到具体 Redis,返回结果 Twemproxy;
- Codis 它是开源解决方案,也是目前使用最多的集群解决方案,基本和 Twemproxy 效果一致,但支持旧节点数据在节点数量变化的情况下恢复到新的状态 hash 节点;
- Redis Cluster 是 Redis 3.0 他自己的集群方案的特点是他的分布式算法不一致 hash,而是 hash 从节点设置槽的概念,以及自己的支持节点;
- 实现业务代码层,创建几个独立的代码层 Redis 例子,在代码层对 key 进行 hash 计算,然后对应 Redis 实例操作数据。这样对 hash 层代码要求较高,包括节点故障后的替代算法方案、数据震荡后的自动脚本恢复、实例监控等。
答:整体存储相关信息,而不是独立存储每个信息,可以有效减少内存的使用。
29.设计分布式锁需要注意哪些事项?答:通常在设计分布式锁时,需要同时满足以下四个约束条件。
- 互斥:在任何时候,只有一个客户端可以持有锁。
- 安全性:即不会形成死锁。当客户端在持有锁的过程中崩溃而不主动解锁时,其持有的锁也可以正确释放,并确保其他客户端可以在以后添加锁。
- 可用性:就 Redis 就锁服务而言,提供锁服务 Redis master 节点停机等不可恢复性故障时,slave 节点可以升级并继续提供服务,支持客户端锁定和解锁;基于分布式一致性算法的锁定服务,如 ETCD 而言,当 leader 节点停机时,follow 节点可以选择新的 leader 继续提供锁定服务。
- 对称性:对于任何锁,锁和解锁必须是同一个客户端,即客户端 A 不能把客户端 B 加的锁解了。
答:集群的实现原理与集群的实现方式有关,如下所述:
- Redis Sentinal 着眼于高可用性,在 Master 自动停机 Slave 提升为 Master,继续提供服务;
- Redis Cluster 注重扩展,注重单个的扩展 Redis 当内存不足时,使用它 Cluster 分片存储。
答:Redis 常见的性能问题如下:
- 写内存快照的主服务器会阻碍主线程的工作。当快照相对较大时,它会对性能产生很大的影响,并会间歇性地暂停服务。因此,最好不要写内存快照;
- Redis 为了主从复制的速度和连接的稳定性,主从库最好在同一局域网中。