🗒️RDB──Redis DataBase
2024-9-11
| 2024-9-12
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password

两个关键问题

  1. 对哪些数据做快照?──执行效率
  1. 做快照时,数据库还能正常操作吗?──Redis 是否阻塞
  类比于:如何取景?也就是说,我们打算把哪些人、哪些物拍到照片中;在按快门前,要记着提醒朋友不要乱动,否则拍出来的照片就模糊了。
  Redis 默认执行的是全量快照
  两个命令生成 RDB 文件:savebgsave
  • save:在主线程中执行,会导致阻塞;
  • bgsave:创建一个子线程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置
这里我就要说到一个常见的误区了,避免阻塞和正常处理写操作并不是一回事。此时,主线程的确没有阻塞,可以正常接收请求,但是,为了保证快照完整性,它只能处理读操作,因为不能修改正在执行快照的数据。──避免阻塞和正常处理写操作并不是一回事
为了快照而暂停写操作,肯定是不能接受的。这里使用写时复制技术(Copy On Write,COW)。bgsave 子线程由主线程 fork 而来,可以共享主线程的所有内存数据。
💡
这里的操作和 AOF 很类似,也是在 fork 子线程的时候,可以共享主线成的所有内存数据。包括 Java 类库中,也有体现。在 String 类中,String 是不可变对象,改变值,会重新生成一个对象。
notion image
  对于两个关键问题的回答:Redis 会默认使用 bgsave 对当前内存中的所有数据做快照,这个操作是子线程在后台完成的,这就允许主线程同时可以修改数据。
如果频繁地执行全量快照,也会带来两方面的开销。
  1. 频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。
  1. bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然,子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁 forkbgsave 子进程,这就会频繁阻塞主线程了。

混合使用 AOF 日志和 RDB 的方法

虽然跟 AOF 相比,快照的恢复速度快,但是,快照的频率不好把握,如果频率太低,两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高,又会产生额外开销,那么,还有什么方法既能利用 RDB 的快速恢复,又能以较小的开销做到尽量少丢数据呢?
混合使用 AOF 日志和 RDB 的方法(Reids4.0):内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。
notion image

📎 参考

 
  • Redis
  • 决策树AOF (Append Only File)日志  
    Loading...
    目录