Redis 持久化的奥秘:主线程、子进程与后台线程的区别及潜在阻塞风险

1. 主线程、子进程和后台线程的联系与区别

image.png

Redis 是一个高性能的键值数据库,以其快速的响应速度和丰富的功能集,广泛应用于各种应用场景。理解 Redis 的线程和进程模型有助于更好地优化其性能。下面,我们将详细探讨 Redis 中的主线程、子进程和后台线程的联系与区别。

进程和线程的区别

  • 进程:进程是资源分配的基本单位。一个进程拥有自己的堆、栈、虚拟内存空间(页表)、文件描述符等资源。操作系统对进程进行管理和调度。

  • 线程:线程是CPU调度和执行的基本单位。一个进程可以包含多个线程,线程之间共享进程的资源,但每个线程有自己的栈和寄存器上下文。

一个进程启动后,如果没有创建额外的线程,这样的进程一般称为主进程或主线程。

Redis 主线程与子进程

  • 主线程:Redis 启动后,主要运行一个进程来接收客户端请求并处理读写操作。这个进程通常称为主线程。它负责Redis的大部分核心功能,包括网络通信、命令处理等。

  • 子进程:Redis在进行RDB快照和AOF重写时,会通过fork系统调用创建子进程。子进程共享主进程的内存,使用写时复制(COW)技术来保证数据的一致性。子进程负责执行持久化操作,不干扰主线程处理客户端请求。

后台线程

从 Redis 4.0 开始,Redis 使用 pthread_create 创建后台线程来执行异步任务,例如异步删除键、延迟关闭文件描述符等。后台线程在创建后会独立运行,并完成指定的任务,提升 Redis 的异步操作能力。

2. Redis 持久化过程中其他潜在的阻塞风险

当 Redis 做 RDB 或 AOF 重写时,一个必不可少的操作就是执行 fork 操作创建子进程。对于大多数操作系统来说,fork 是一个重量级操作。虽然 fork 创建的子进程不需要拷贝父进程的物理内存空间,但会复制父进程的内存页表。例如,对于 10GB 的 Redis 进程,需要复制大约 20MB 的内存页表,因此 fork 操作耗时与进程总内存量息息相关。如果使用虚拟化技术,特别是 Xen 虚拟机,fork 操作会更耗时。

fork 耗时问题定位

对于高流量的 Redis 实例(OPS 可达 5 万以上),如果 fork 操作耗时在秒级别,将拖慢 Redis 几万条命令的执行,对线上应用延迟影响非常明显。正常情况下,fork 耗时应该是每 GB 消耗 20 毫秒左右。可以在 info stats 统计中查 latest_fork_usec 指标获取最近一次 fork 操作耗时,单位微秒。

image.png

如何改善 fork 操作的耗时

  1. 优先使用物理机或者高效支持 fork 操作的虚拟化技术。
  2. 控制 Redis 实例最大可用内存,fork 耗时跟内存量成正比。线上建议每个 Redis 实例内存控制在 10GB 以内。
  3. 降低 fork 操作的频率,如适度放宽 AOF 自动触发时机,避免不必要的全量复制等。
3. 为什么主从库间的复制不使用 AOF?
  1. IO效率:RDB 文件是二进制文件,无论是写入磁盘,还是通过网络传输,IO 效率都比记录和传输 AOF 高。RDB 文件更紧凑,且不需要逐条记录命令。
  2. 恢复效率:在从库进行恢复时,用 RDB 的恢复效率要高于用 AOF。RDB 文件可以一次性恢复大量数据,而 AOF 文件需要逐条执行命令恢复数据。

通过合理优化和设计,Redis 在保证高性能的同时,能够有效地持久化数据和保持主从数据一致性。在实际应用中,理解并优化 Redis 的持久化机制,可以显著提升系统的稳定性和性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搬砖的小熊猫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值