第十章 第1~9章常见问题答疑

第十章 第1~9章常见问题答疑

整数数组和压缩列表作为底层数据结构的优势是什么 ?

  • 整数数组和压缩列表的设计,充分体现了 Redis“又快又省”特点中的“省”,也就是节省内存空间。
  • 整数数组和压缩列表都是在内存中分配一块地址连续的空间,然后把集合中的元素一个接一个地放在这块空间内,非常紧凑。
  • 因为元素是挨个连续放置的,我们不用再通过额外的指针把元素串接起来,这就避免了额外指针带来的空间开销。

Untitled

为什么主从库间的复制不使用 AOF ?

  • RDB 文件是二进制文件,无论是要把 RDB 写入磁盘,还是要通过网络传输 RDB,IO 效率都比记录和传输 AOF 的高。
  • 在从库端进行恢复时,用 RDB 的恢复效率要高于用 AOF。

在主从切换过程中,客户端能否正常地进行请求操作呢 ?

  • 主从集群一般是采用读写分离模式,当主库故障后,客户端仍然可以把读请求发送给从库,让从库服务。
  • 但是,对于写请求操作,客户端就无法执行了。

如果想要应用程序不感知服务的中断,还需要哨兵或客户端再做些什么吗 ?

  • 如果不想让业务感知到异常,客户端只能把写失败的请求先缓存起来或写入消息队列中间件中,等哨兵切换完主从后,再把这些写请求发给新的主库 。
  • 当哨兵完成主从切换后,会通过 pub 模式主动通知客户端更新主库地址(所以在有集群的时候,不推荐写死主库地址,可以通过 sentinel get-master-addr-by-name 从哨兵集群去取)或者 客户端也可以主动和哨兵通信获取最新的主库地址。

Redis 进行 rehash 的时机 ?

  • Redis会使用装载因子【哈希表中所有entry的个数除以哈希表的哈希桶个数】来判断是否需要做rehash。
  • 装载因子 >=1,同时哈希表被允许进行rehash(进行RDB生成和AOF重写时,哈希表不允许 rehash)。
  • 装载因子 >=5,即使正在进行 RDB 或 AOF 重写,也要立刻进行rehash。

采用渐进式 hash 时,如果实例暂时没有收到新请求,是不是就不做 rehash 了 ?

  • 渐进式rehash, 对于每次请求的时候会顺带做一部分的rehash
  • 此外Redis 会执行定时任务,定时任务中就包含了 rehash 操作。
  • 所谓的定时任务,就是按照一定频率(例如每 100ms/ 次)执行的任务。
  • 在 rehash 被触发后,即使没有收到新请求,Redis 也会定时执行一次 rehash 操作;而且,每次执行时长不会超过 1ms,以免对其他任务造成影响。

Redis 中用 fork 创建的子进程有哪些 ?

  • 创建 RDB 的后台子进程,同时由它负责在主从同步时传输 RDB 给从库
    • Redis通过两个命令来生成RDB文件,分别是save和bgsave。
    • save,在主线程中执行,会导致阻塞。
    • bgsave,创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是Redis的默认配置。
  • 通过无盘复制方式传输 RDB 的子进程
  • bgrewriteaof 子进程

Untitled

写时复制的底层实现机制是什么 ?

写时复制的效果:bgsave 子进程相当于复制了原始数据,而主线程仍然可以修改原来的数据。

  • 对 Redis 来说,主线程 fork 出 bgsave 子进程后,bgsave 子进程实际是复制了主线程的页表。
  • 这些页表中,就保存了在执行 bgsave 命令时,主线程的所有数据块在内存中的物理地址。
  • 这样一来,bgsave 子进程生成 RDB 时,就可以根据页表读取这些数据,再写入磁盘中。
  • 如果此时,主线程接收到了新写或修改操作,那么,主线程会使用写时复制机制。
  • 具体来说,写时复制就是指,主线程在有写操作时,才会把这个新写或修改后的数据写入到一个新的物理地址中,并修改自己的页表映射。

举例说明写时复制

  • bgsave 子进程复制主线程的页表以后,假如主线程需要修改虚页 7 里的数据,那么,主线程就需要新分配一个物理页(假设是物理页 53),然后把修改后的虚页 7 里的数据写到物理页 53 上,而虚页 7 里原来的数据仍然保存在物理页 33 上。
  • 这个时候,虚页 7 到物理页 33 的映射关系,仍然保留在 bgsave 子进程中。
  • 所以,bgsave 子进程可以无误地把虚页 7 的原始数据写入 RDB 文件。

Untitled

replication buffer 和 repl_backlog_buffer 的区别 ?

replication buffer

  • Redis 主从库在进行复制时,当主库要把全量复制期间的写操作命令发给从库时,主库会先创建一个客户端,用来连接从库,然后通过这个客户端,把写操作命令发给从库。
  • 在内存中,主库上的客户端就会对应一个 buffer,这个 buffer 就被称为 replication buffer。
  • Redis 通过 client_buffer 配置项来控制这个 buffer 的大小。
  • 主库会给每个从库建立一个客户端,所以 replication buffer 不是共享的,而是每个从库都有一个对应的客户端。

repl_backlog_buffer

  • repl_backlog_buffer 是一块专用 buffer,在 Redis 服务器启动后,开始一直接收写操作命令,这是所有从库共享的。
  • 主库和从库会各自记录自己的复制进度,所以,不同的从库在进行恢复时,会把自己的复制进度(slave_repl_offset)发给主库,主库就可以和它独立同步。

Untitled

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿小羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值