栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis 面试相关问题【总结】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis 面试相关问题【总结】

1、Redis是单线程还是多线程?

  • Redis在不同版本之间采用的线程模型是不一样的,在Redis4.0版本之前会用到的是单线程模型,在4.0版本之后增加了多线程的支持;
  • 在4.0之前虽然我们说Redis是单线程,也只能说它的网络I/O线程以及Set和Get操作是由一个线程完成的。但是Redis的持久化、集群同步还是使用其它线程来完成;
  • 4.0之后虽然添加了多线程的支持,只要是体现在大数据的异步删除功能上,例如:unlink key、flushdb async、flushall async等。

2、为什么Redis在4.0之前会选择使用单线程?而且使用单线程还那么快?

  • 选择单线程个人觉得主要是使用简单,不存在锁竞争,可以在无锁的情况下完成所有操作,不存在死锁和线程切换带来的性能和时间上的开销,但同时单线程也不能完全发挥出多核CPU的性能。

    至于为什么单线程那么快我觉得有以下几个原因:

  • Redis的大部分操作都是在内存中完成,内存中的执行效率本身就快,并且采用了高效的数据结构,比如哈希表和跳表;

  • 使用单线程避免了多线程的竞争,省去了多线程切换带来的时间和性能开销,并且不会出现死锁;

  • 采用 I/O 多路复用机制处理大量客户端的socket请求,因为这是基于非阻塞的 I/O 模型,这就让Redis可以高效地进行网络通信,I/O的读写流程不再阻塞。

3、Redis是如何保证数据不丢失的呢?

  • Redis数据存储在内存中的,为了保证Redis数据不丢失,那就要把数据从内存存储到磁盘上,以便在服务器重启后还能够从磁盘中恢复原有数据,这就是Redis的数据持久化。

    Reids持久化有三种方式:

  • AOF日志(Append Only File,文件追加方式):记录所有的操作指令,并以文本的形式追加到文件中;

  • RDB快照(Redis DataBase):将某一时刻的内存数据,以二进制的方式写入磁盘;

  • 混合持久化方式:Redis 4.0新增了混合持久化的方式,集成了RDB和AOF的优点。

4、分别说说AOF和RDB的实现原理?

  • AOF采用的是写后日志的方式,Redis先执行命令把数据写入内存,然后再记录日志到文件中。AOF日志记录的是操作命令,不是实际的数据,如果采用AOF方法做故障恢复时需要将全量日志都执行一遍。
  • RDB采用的是内存快照的方式,它记录的是某一刻的数据,而不是操作,所以采用RDB方法做故障恢复时只需直接把RDB文件读入内存即可,实现快速恢复。

5、AOF采用的是“写后日志”的方式,我们平时用的MySQL则采用的是“写前日志”,那Redis为什么要先执行命令,再把数据写入日志呢?

  • 这主要是由于Redis在写入日志前,不对命令进行语法检查,所以只记录执行成功的命令,避免出现记录错误命令的情况,而且在命令执行后再写日志不会阻塞当前的写操作。

6、后写日志又有什么风险呢?

  • 后写日志主要有两个风险可能发生:
  • 数据可能会丢失:如果Reids刚执行完命令,此时发生故障宕机,会导致这条命令存在丢失的风险;
  • 可能阻塞其它操作:AOF日志其实也是在主线程中执行,所以当Redis把日志文件写入磁盘的时候,还是会阻塞后续的操作无法执行。

7、RDB做快照时会阻塞线程吗?

  • Redis提供了两个命令来生成RDB快照文件,分别是 save 和 bgsave。save 命令会在主线程中执行,会导致线程阻塞,而 bgsave 命令则会创建一个子进程,用于写入RDB文件的操作,避免了对主线程的阻塞,这也是Redis RDB的默认配置。

8、RDB做快照的时候数据能修改吗?

  • save是同步的会阻塞客户端命令,bgsave的时候是可以修改的。

9、那么Redis是怎么解决在 bgsave 做快照的时候允许数据修改呢?

  • 这里主要是利用 bgsave 的子线程实现的,具体操作如下:
  • 如果主线程执行读操作,则主线程和 bgsave 子线程互相不影响;
  • 如果主线程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会把改副本数据写入RDB文件,在这个过程中,主线程仍然可以直接修改原来的数据。

10、Redis是如何实现高可用的?

  • Redis实现高可用主要有三种方式:主从复制、哨兵模式,以及Redis集群。

1)主从复制:将从前的一台Redis服务器,同步数据到多台 “从Redis” 服务器上,即一主多从的模式,这个跟MySQL主从复制原理一样。

2)哨兵模式:使用Redis主从服务的时候,会有一个问题,就是当Redis的主从服务器出现故障宕机时,需要手动进行恢复,为了解决这个问题,Redis增加了哨兵模式(因为哨兵模式做到了可以监控主从服务器,并且提供了容灾恢复的功能)。

3)Redis Cluster(集群):Reids Cluster是一种分布式去中心化的运行模式,是在Redis 3.0版本中推出的Redis集群方案,它将数据分布在不同的服务器上,以此来降低系统对单节点的依赖,从而提高Redis服务的读写性能。

11、使用哨兵模式在数据上有副本数据做保证,在可用性上又有哨兵监控,一旦master宕机会选举slave节点为master节点,这种已经满足了我们的生产环境需要,那为什么还需要使用集群模式呢?

  • 哨兵模式归根节点还是主从模式,在主从模式下我们可以通过增加slave节点来扩展读并发能力,但是没办法扩展写能力和存储能力,存储能力只能是master节点能够承载的上限。所以为了扩展写能力和存储能力,我们就需要引入集群模式。

12、集群中那么多Master节点,Reids Cluster在存储的时候如何确定选择哪个节点呢?

  • Redis Cluster 采用的是类一致性哈希算法实现节点选择的。(至于什么是一致性哈希算法下篇文章介绍)
  • Redis Cluster 将自己分成了 16384 个Slot(槽位),哈希槽类似于数据分区,每个键值对都会根据它的key,被映射到一个哈希槽中,具体执行过程分为大致两步:
    1. 根据键值对的key,按照 CRC16 算法计算一个 16bit 的值;
    2. 再用 16bit 的值对16384取模,得到 0~16383 范围内的模数,每个模数代表一个相应编号的哈希槽。
  • 每个Redis节点负责处理一部分槽位,假如你有三个master节点ABC,每个节点负责的槽位如下:
节点处理槽位
A0 - 5000
B5001 - 10000
C10001 - 16383

这样就实现了cluster节点的选择。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/958939.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号