Doris FE 节点的元数据是如何存储和同步的?
在 Apache Doris 中,FE(Frontend,前端节点)负责查询解析、优化、规划以及整个集群的元数据管理。为了保证高可用性(HA)和极高的读写性能,Doris FE 的元数据存储和同步机制经过了精心设计。
总的来说,Doris FE 的元数据采用了“内存 + Checkpoint(Image) + Edit Log(Journal)”的存储机制,并依赖 BDB JE (Berkeley DB Java Edition) 来实现分布式一致性和数据的同步。
以下是详细的解析:
一、 FE 节点的角色划分
理解同步机制前,需要先明确 FE 的三种角色,因为角色决定了它们在同步中的职责:
- Master (Leader):集群中唯一可写的 FE 节点。负责处理元数据的修改请求,并生成 Edit Log。
- Follower:参与选举和多数派协议。同步 Master 的 Edit Log,可以提供读服务。当 Master 宕机时,Follower 可以被选举为新的 Master。
- Observer:不参与选举和多数派协议(无投票权)。仅异步同步 Edit Log,提供读服务。用于横向扩展 FE 的读并发能力,而不会增加多数派同步的延迟。
二、 元数据的存储机制 (Storage)
FE 的元数据主要存储在三个地方:
内存 (Memory)
- 机制:FE 启动后,会将全量元数据加载到内存中。
- 目的:所有的查询规划、权限校验、表结构查看等读操作,全部直接在内存中完成,无需读盘,因此性能极高(通常是微秒级响应)。
Edit Log (变更日志 / Journal)
- 机制:任何对元数据的修改(如建库建表、插入数据产生的新版本、用户权限修改等),都会先序列化为一条 Edit Log 写入磁盘。
- 目的:保证增量修改的持久化。Doris 使用了 BDB JE 作为底层引擎来存储这些日志。
Image (快照 / 镜像)
- 机制:内存中全量元数据在某一时刻的快照(Checkpoint)。
- 目的:如果只有 Edit Log,日志会随着时间无限增长,导致 FE 重启时回放日志的时间过长。因此需要定期将内存状态 dump 成 Image 文件。FE 重启时,只需加载最新的 Image,然后回放该 Image 之后的 Edit Log 即可。
三、 元数据的同步机制 (Synchronization)
元数据的同步核心依赖于 BDB JE 的复制状态机(类似 Paxos/Raft 协议)。
1. 增量同步 (Edit Log 的写入与复制)
当一个写操作(如 CREATE TABLE)到达 FE 时:
- 请求转发:如果请求发给了 Follower/Observer,它们会将写请求转发给 Master。
- Master 处理:Master 在内存中校验并执行该操作,生成一条 Edit Log。
- BDB JE 同步:Master 通过 BDB JE 将 Edit Log 发送给所有的 Follower。
- 多数派确认:当 超过半数 (N/2 + 1) 的节点(包括 Master 自己和部分 Follower)将该 Edit Log 成功写入本地磁盘后,Master 认为该操作持久化成功。
- 异步同步:Observer 节点会异步地从 BDB JE 拉取最新的 Edit Log 并写入本地。
- 内存回放:Follower 和 Observer 在收到 Edit Log 后,会在自己的内存中回放这些日志,从而保证自己的内存元数据与 Master 保持一致。
2. 全量同步 (Image 的生成与 Checkpoint 机制)
Image 的生成通常不在 Master 节点上进行,这是为了避免 dump 庞大的内存快照时引发 Master 的 Full GC 或占用过多 CPU/磁盘 IO,从而影响集群可用性。
Checkpoint 同步流程:
- 选举 Checkpoint 节点:通常由某个 Follower 或 Observer 节点承担生成 Image 的任务(称为 Checkpoint 线程)。
- 生成 Image:该节点根据自己内存中的元数据状态,将其序列化并写入本地磁盘,生成一个新的 Image 文件(文件名通常包含该快照对应的最新 Edit Log 的 ID,如
image.12345)。 - Push 给 Master:生成完成后,该节点会通过 HTTP 协议将新的 Image 文件 Push 给 Master 节点。
- Master 确认并清理:Master 接收并校验 Image 成功后,会将其保存在本地,并删除旧的 Image 和已经被包含在 Image 中的过期 Edit Log,释放磁盘空间。
- 其他节点拉取:其他 FE 节点在发现有新的 Image 后,也会清理自己的旧日志。
四、 FE 节点的启动与恢复流程
当一个 FE 节点(无论是 Master 还是 Follower)重启时,恢复流程如下:
- 从 BDB JE 的目录和 Image 目录中,找到最新的
image.xxx文件。 - 将
image.xxx加载到内存中,此时内存恢复到了xxx这个事务 ID 时的状态。 - 利用 BDB JE,从
xxx + 1开始读取后续的 Edit Log。 - 在内存中逐条回放这些 Edit Log。
- 回放完成后,FE 启动成功,开始对外提供服务(参与选举或同步新日志)。
五、 总结与优势
- 高可用:基于 BDB JE 的多数派协议,即使少数 FE 节点宕机(如 3 节点挂掉 1 个),集群元数据依然可读可写,不会丢失。
- 高性能:读操作纯内存处理;写操作只需顺序追加 Edit Log 且满足多数派即可返回,延迟低。
- 读扩展性:通过添加 Observer 节点,可以线性扩展元数据的读取能力(如应对高并发的查询请求),而不会拖慢 Master 的写入性能。
- 系统稳定性:将消耗资源的 Checkpoint (Image 生成) 操作转移到非 Master 节点,极大地保障了 Master 的稳定运行。