1-9 课后解答总结

1、整数数组和压缩列表在 Redis 数据结构中的优势是什么?

Redis 的特定就是“又快又省”,其中整数数组和压缩列表在内存空间使用上都是使用一段连续的空间,布局紧凑,并且不需要额外空间来存储指针。Redis 使用不同的数据结构就是在性能和内存做出平衡。

2、AOF 重写的过程中有没有什么潜在的风险?

(1)fark 子进程阻塞主线程风险

  • 成这项任务,其中在 fark 子进程的过程中需要主线程创建和初始化用于管理这个子进程的数据结构,即 bgrewriteaof 的进程控制块 PCB,而该 PCB 的初始化过程需要由主线程将自己 PCB 进行拷贝复制,其中就包括主线程的页表的拷贝,而该页表的大小由 Redis 的内存大小有关,内存越大,其页表也就越大,进而导致主线程的 fark 操作消耗的时间越大。

(2)主线程申请内存空间导致的阻塞风险

  • 当正在进行 AOF 重写的过程中,主线程是不被阻塞的,仍然可以执行读写操作,但是为了使得 bgrewriteaof 子进程根据复制主线程页表中的数据对应的物理页面对应物理位置的数据不发生改变,仍然可以保持读取到的数据是开启生成快照时数据保持一致,因此 Redis 采用 WOC 读写复制机制来解决,需要主线程在执行写操作前申请新的内存地址将需要操作的数据复制到新的内存中,然后修改自己的页表映射,之后再执行写操作,这样主线程就可以在新地址上进行数据操作,不会对 bgrewriteaof 执行 AOF 重写过程带来数据被修改变化的影响,但是如果主线程需要操作的数据是一个 bigkey(数据量的大的集合类型数据),那么主线程需要额外申请的内存空间比较大,而申请内存的过程需要经历寻找合适的内存空间地址的时间以及锁的时间,这就很容易让主线程陷入阻塞状态。

3、为什么进行 AOF 复制的时候,不让主线程和 bgrewriteaof 进程共享使用 AOF 文件?

如果都用 AOF 日志的话,主线程要写,bgrewriteaof 子进程也要写,这两者会竞争文件系统的锁,这就会对 Redis 主线程的性能造成影响。

4、使用一个 2 核 CPU、4GB 内存、500GB 磁盘的云主机运行 Redis,Redis 数据库的数据量大小差不多是 2GB。当时 Redis 主要以修改操作为主,写读比例差不多在 8:2 左右,也就是说,如果有 100 个请求,80 个请求执行的是修改操作。在这个场景下,用 RDB 做持久化有什么风险吗?

  • 内存空间不足的风险
    • 进行生成 RDB 文件操作期间,如果主线程需要执行写操作就需要开辟额外的内存空间,而该 Redis 的写读比例大概 8:2,那么就需要大概 1.6 G 的额外的内存空间,这样一来加上 Redis 需要存储的所有数据需要的 2G 内存就需要 3.6 G 内存,对于 4G 内存的云主机而言,内存消耗方面就接近饱和了,如果此时 Redis 实例还需要执行大量的键值对修改等写操作,那么就会导致内存不够,如果云主机开启了 Swap 机制,那么就会选择将一部分的数据写入磁盘中以减少对内存的占用,但是如果云主机并没有开启,那么就会触发 OOM,这就会导致整个 Redis 实例即将被系统 kill 掉的风险。
  • 主线程与子进程 bgrewrietaof 竞争 CPU 的风险
    • Redis 的主线程运行需要占用一个 CPU,当进行 AOF 复制时就需要主线程 fark 子进程 bgrewrietaof,而云主机的 CPU 是双核的,如果此时 Redis 中还存在其他的后台进程,那么就会导致 CPU 不够用,主线程,bgrewriteaof 子进程,后台进程都在竞争 CPU 的使用权,那么就会导致 Redis 主线程被阻塞的风险

5、为什么主从复制的时候不选择使用 AOF?

  • RDB 是二进制文件,无论是在网络传输,还是将 RDB 写入磁盘,其效率都要比 AOF 文件高。
  • 使用 RDB 快照的方式进行复制,只需要从库将 RDB 文件加载到本地内存中即可,比一个个执行 AOF 文件中的操作复制数据要快。

6、在主从切换中,客户端能够正常的进行请求操作?

由于 Redis 采用的是读写分离的方式,因此当主库故障之后,客户端的读操作仍然可以向其他从库发送获取数据的请求,但是由于写操作必须由主库来执行,因此客户端的写操作是不能正常地进行请求的。

7、如果希望应用程序对服务的断开没有感知,需要客户端和哨兵做什么?

  • 当主库故障之后,就需要进行主库切换,其中这一过程中,应用程序是无法执行客户端发送的写操作的请求的,因此就需要客户端对主库切换整个过程进行监控,这就需要哨兵在自己的 pub/sub 发布订阅机制中能够提供主库切换过程中各个关键事件的信息的提供,同时需要客户端主动的去哨兵进行订阅这些信息。
  • 当客户端主动订阅到此时正在进行主库切换,应用程序无法执行写操作,因此就需要客户端能够支持发送的写操作做个缓存的功能,当订阅到主从切换完成之后再将缓存中的写操作请求重新发送出去。

8、哨兵实例的数量是不是越多越好,down_after_milliseconds 设置的是不是越长越好?

(1)哨兵实例越多

  • 优点
    • 其对主库是否客观下线的判断的错判率降低
  • 缺点
    • 再判断主库是否客观下线和进行 Leader 选举投票的时候,由于需要拿到一半以上的票数,但是由于总哨兵实例的数量增加,那么其需要等待得到的票数就越多,其投票的时间变长,就会导致客户端的积压的写请求数量越来越多导致存在溢出的可能,使得出现请求丢失的错误。还有由于某些请求由响应时间的限制,如果由于主库切换时间过长使得超过了请求响应超时的最大时间的限制,导致触发超时报警。

(2)down_after_milliseconds 设置的太长

  • 可能会导致主库已经发生了故障,但是哨兵集群过了很长一段时间才判断出来,使得降低了 Redis 的可用性。

9、为什么 Redis 不直接使用一张表记录键值对与实例之间的对应关系?

  • 由于键值对的数量要比哈希槽的数量要多,因此在与记录哈希槽与实例之间的对应关系相比消耗的内存要大;
  • 如果 Redis 实例进行了增加和删除,使用记录键值对与实例对应关系的方式就会因为重新进行哈希槽分配的发生的数据与实例对应关系的改变需要对表进行修改,如果是单线程来执行,就是串行执行,效率低,如果采用多线程执行修改任务,就需要额外的锁开销。
  • 存储大量的数据的时候,哈希桶的数量就是因为少于总数量很多,并且表需要内存会随着数据量的增加消耗的内存越多,而哈希槽的数量是固定的,记录哈希槽与实例对应关系的映射表所需要的内存固定。并且使用记录哈希槽与实例的对应关系使得表中数据量少,当发生哈希槽与实例对应关系发生改变的时候,需要的修改表消耗的时间也少。

10、rehash 机制的触发条件

装载因子 = Redis 中全量哈希表中的 entry 总数量 / 哈希表总哈希桶数量
需要注意的是,当 Redis 实例此时正在执行 RDB 的生成或者是正在执行 AOF 的重写时,是不允许哈希表进行 rehash 操作的。

  • 当装载因子 >= 1 的时候就允许哈希表可以进行 rehash 操作,当装载因子等于 1 的时候,最好的情况就是每个哈希桶中都只有一个 entry 数据,而之后在添加新的 entry 数据的时候就会产生哈希链,从而降低访问数据的效率,因此将等于1设置为运行哈希表执行 rehash 操作的条件。
  • 当装载因子 >= 5,此时哈希表中的总 entry 数据量大于哈希桶个数的五倍,哈希表中肯定已经存在了大量的较长的哈希链了,Redis 的性能大大降低,因此需要强制哈希表立即执行 rehash 操作。

11、采取渐进式 rehash 的方式时,如果 Redis 实例在没有接收到新的写请求的时候,就不会进行 rehash 操作嘛?

Redis 为了避免在进行 rehash 操作时,会因为数据量太大会阻塞主线程,增加 Redis 的响应时间,降低 Redis 的性能,因此选择了渐进式 rehash 的方式,每当 Redis 实例在接收完成一条写操作的时候就从哈希表的第一个哈希桶的位置为起始对该哈希桶中存储的所有的 entries 数据进行 rehash 操作,直至哈希表中的所有的哈希桶中的 entries 全部 rehash 完毕。但是如果 Redis 实例长时间没有接收到写操作,也还是会执行 rehash 操作,因为 rehash 操作存在于定时任务中,并且每次执行 rehash 操作不会超过 1ms,避免对其他的任务造成影响。

12、replication buffer 和 repl_backlog_buffer 的区别?

Redis 在进行主从复制的时候,首先会主库会为每个需要进行全量数据复制的从库各自建立一个客户端,每个客户端中都有一个 buffer 缓冲区,而这个缓冲区也就是 replication buffer 复制缓冲区,也就是说每个从库与主库之间都有一个客户端,因此 replication buffer 这个缓冲区是各个从库非共享的。而 repl_backlog_buffer 复制积压缓冲区是在主库中的一部分的内存,这个是所有从库共享的,主从库都会记录自己的复制进度,所有每个从库与主库进行同步的时候都会将自己的复制进度发送给主库,主库就可以对它独立同步。在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值