专注Java教育14年 全国咨询/投诉热线:444-1124-454
星辉LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 职业指南 距离进入大厂就只差redis集群面试题

距离进入大厂就只差redis集群面试题

更新时间:2022-12-28 15:15:31 来源:星辉 浏览719次

1.谈谈Redis集群数据hash分片算法

Redis 集群将所有数据划分16384个slots,每个节点负责其中一部分槽位。当Redis 集群的客户端来连接集群时,它也会得到一份集群的槽位信息并将其缓存到客户端本地,这样当客户端要查找某个key时,可以根据槽位定位算法定位到目标节点。

槽位定位算法

集群默认会对key值使用crc16算法进行hash,得到一个整数值,然后这个整数值对16384进行取模运算来得到具体的槽位。

Hash_slot = CRC16(key)mod13684

再根据槽位和节点的对应关系就可以定位到key具体是在那个Redis节点上。

redis集群面试题

2.Redis执行命令竟然有死循环阻塞Bug

Redis有个RANDOMKEY命令可以从Redis中随机取出一个key,这个命令可能导致Redis死循环阻塞。

RANDOMKEY在随机拿出一个key之后,首先会检验这个key是否过期,如果该key过期,那么Redis会删除它,这个过程就是惰性删除,但是清理完了之后还不能结束,Redis会再找出一个没过期的key返回给客户端。

此时,Redis则会继续随机拿出一个key,然后再判断它是否过期,直到找到一个没过期的key返回给客户端。

这里就有一个问题,如果此时Redis中有大量的key过期,但还未来得及被清理掉,这个循环就会持续很久才能结束,这样就会导致RANDOMKEY命令执行耗时变长,影响Redis性能。

以上流程,其实是master上执行的。如果在slave上执行RANDOMKEY,那么问题更严重。

slave是不会自己清理过期的key,当一个key要过期时,master会先清理删除它,之后master向slave发送一个DEL命令,告知slave也删除这个key,以此达到主从一致。

假设Redis中存在大量已过期还未来得及清理的key,那么在slave上执行RANDOMKEY时,就会发生一下问题:

1、slave随机取出一个key,判断是否已经过期。

2、key已经过期,但是slave不会删除它,而是继续随机寻找不过期的key

3、由于大量key都已过期,那slave就会找不到符合条件的key,就会进入死循环。

这个Bug直到5.0才被修复,修复方法就是在slave中设置一个最大查找次数,无论找到与否,到了这个最大次数就退出循环。

3.一次线上事故,Redis主从切换导致了缓存雪崩

我们假设,slave的机器时钟比master走的快很多。

此时,Redis master 里设置了过期时间的key,从slave角度来看,可能会有很多在master里没过期,在slave里面已经过期了的数据。

如果此时操作主从切换,把slave提升为新的master,新的master就会开始大量清理过期的key,此时就会导致以下结果:

1、master大量清理过期key,主线程可能会发生阻塞,无法及时处理客户端请求。

2、Redis中数据大量过期,引发缓存雪崩。

所以,我们一定要保证主从库的机器时钟一致,避免发生这些问题。

4.Redis持久化RDB、AOF、混合持久化

Redis持久化分为:RDB、AOF、混合持久化(redis4.0引入)

RDB的实现原理、优缺点

描述:类似于快照。在某个时间点,将 Redis 在内存中的数据库状态(数据库的键值对等信息)保存到磁盘里面。RDB 持久化功能生成的 RDB 文件是经过压缩的二进制文件。

有两个 Redis 命令可以用于生成 RDB 文件,一个是 SAVE,另一个是 BGSAVE。

开启:使用 save point 配置

save 900 1 #900秒内有1个key发生了变化,则触发保存RDB文件
save 300 10 #300秒内有10个key发生了变化,则触发保存RDB文件
save 60 10000 #60秒内有10000个key发生了变化,则触发保存RDB文件

关闭:1)注释掉所有save point 配置可以关闭 RDB 持久化。2)在所有 save point 配置后增加:save "",该配置可以删除所有之前配置的 save point。

SAVE:生成 RDB 快照文件,但是会阻塞主进程,服务器将无法处理客户端发来的命令请求,所以通常不会直接使用该命令。

BGSAVE:fork 子进程来生成 RDB 快照文件,阻塞只会发生在 fork 子进程的时候,之后主进程可以正常处理请求.

RDB 的优点:1)RDB 文件是是经过压缩的二进制文件,占用空间很小,它保存了 Redis 某个时间点的数据集,很适合用于做备份。 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。

2)RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心。

3)RDB 可以最大化 redis 的性能。父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。

4)RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

RDB 的缺点:1)RDB 在服务器故障时容易造成数据的丢失

2)RDB 保存时使用 fork 子进程进行数据的持久化,如果数据比较大的话,fork 可能会非常耗时,造成 Redis 停止处理服务N毫秒。如果数据集很大且 CPU 比较繁忙的时候,停止服务的时间甚至会到一秒。

3)Linux fork 子进程采用的是 copy-on-write 的方式。在 Redis 执行 RDB 持久化期间,如果 client 写入数据很频繁,那么将增加 Redis 占用的内存,最坏情况下,内存的占用将达到原先的2倍。刚 fork 时,主进程和子进程共享内存,但是随着主进程需要处理写操作,主进程需要将修改的页面拷贝一份出来,然后进行修改。极端情况下,如果所有的页面都被修改,则此时的内存占用是原先的2倍。

AOF的实现原理、优缺点

描述:保存 Redis 服务器所执行的所有写操作命令来记录数据库状态,并在服务器启动时,通过重新执行这些命令来还原数据集。

可以通过配置:appendonly yes 开启,使用配置 appendonly no 可以关闭 AOF 持久化

AOF 持久化功能的实现可以分为三个步骤:命令追加、文件写入、文件同步。

appendfsync 参数有三个选项:

1)always:每处理一个命令都将 aof_buf 缓冲区中的所有内容写入并同步到AOF 文件,即每个命令都刷盘。

2)everysec:将 aof_buf 缓冲区中的所有内容写入到 AOF 文件,如果上次同步 AOF 文件的时间距离现在超过一秒钟, 那么再次对 AOF 文件进行同步, 并且这个同步操作是异步的,由一个后台线程专门负责执行,即每秒刷盘1次。

3)no:将 aof_buf 缓冲区中的所有内容写入到 AOF 文件, 但并不对 AOF 文件进行同步, 何时同步由操作系统来决定。即不执行刷盘,让操作系统自己执行刷盘。

  • AOF 的优点:1)AOF 比 RDB可靠。你可以设置不同的 fsync 策略:no、everysec 和 always。默认是 everysec,在这种配置下,redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据。

2)AOF文件是一个纯追加的日志文件。即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机等等), 我们也可以使用 redis-check-aof 工具也可以轻易地修复这种问题。

3)当 AOF文件太大时,Redis 会自动在后台进行重写:重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。整个重写是绝对安全,因为重写是在一个新的文件上进行,同时 Redis 会继续往旧的文件追加数据。当新文件重写完毕,Redis 会把新旧文件进行切换,然后开始把数据写到新文件上

4)AOF 文件有序地保存了对数据库执行的所有写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。如果你不小心执行了 FLUSHALL 命令把所有数据刷掉了,但只要 AOF 文件没有被重写,那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

  • AOF 的缺点

1)对于相同的数据集,AOF 文件的大小一般会比 RDB 文件大。

2)根据所使用的 fsync 策略,AOF 的速度可能会比 RDB 慢。通常 fsync 设置为每秒一次就能获得比较高的性能,而关闭 fsync 可以让 AOF 的速度和 RDB 一样快。

生产环境都可以启用,redis启动时如果既有rdb文件,又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更安全一点。

混合持久化

通过如下配置开启混合持久化(必须先开启aof)

aof-use-rdb-preamble yes

混合持久化本质是通过 AOF 后台重写(bgrewriteaof 命令)完成的,不同的是当开启混合持久化时,fork 出的子进程先将当前全量数据以 RDB 方式写入新的 AOF 文件,然后再将 AOF 重写缓冲区(aof_rewrite_buf_blocks)的增量命令以 AOF 方式写入到文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。

优点:结合 RDB 和 AOF 的优点, 更快的重写和恢复。

缺点:AOF 文件里面的 RDB 部分不再是 AOF 格式,可读性差。

以上就是“距离进入大厂就只差redis集群面试题”,你能回答上来吗?如果想要了解更多的Java面试题相关内容,可以关注星辉Java官网。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>