Skip to content

Commit a4882da

Browse files
committed
[FLUSS-2021] Add design documents for lake snapshot file storage migration
- Add detailed design document - Add implementation code examples - Add implementation checklist - Add summary and guide This addresses issue apache#2021: Move lake snapshot from ZK to file storage
1 parent 453d64b commit a4882da

File tree

7 files changed

+2017
-0
lines changed

7 files changed

+2017
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# Lake Snapshot 从 ZooKeeper 迁移到文件系统 - 实现指南
2+
3+
> **Issue**: [#2021 - Consider move lake snapshot from zk to file just like did for kv snapshot](https://github.com/apache/fluss/issues/2021)
4+
5+
## 📖 快速导航
6+
7+
### 1️⃣ 首先阅读:总览
8+
- **[SUMMARY.md](SUMMARY.md)** - 问题背景、解决方案总览、工作量评估
9+
10+
### 2️⃣ 深入理解:详细设计
11+
- **[lake-snapshot-migration-design.md](lake-snapshot-migration-design.md)** - 完整的技术设计文档
12+
- 核心设计思路
13+
- 数据结构设计
14+
- 文件路径规范
15+
- 向后兼容策略
16+
- 详细实施步骤
17+
- 风险和缓解措施
18+
19+
### 3️⃣ 开始编码:代码示例
20+
- **[implementation-code-examples.md](implementation-code-examples.md)** - 完整的代码示例
21+
- LakeTableSnapshotHandle 完整代码
22+
- LakeTableSnapshotHandleJsonSerde 完整代码
23+
- FlussPaths 新增方法
24+
- ZooKeeperClient 核心修改
25+
- CoordinatorEventProcessor 修改
26+
- 测试代码示例
27+
28+
### 4️⃣ 逐步实施:检查清单
29+
- **[implementation-checklist.md](implementation-checklist.md)** - 逐步实施指南
30+
- 阶段 1: 新增基础数据结构
31+
- 阶段 2: 添加路径工具方法
32+
- 阶段 3: 修改 ZooKeeper 客户端
33+
- 阶段 4: 修改 Coordinator 逻辑
34+
- 阶段 5: 全面测试
35+
- 阶段 6: 文档和代码审查
36+
37+
---
38+
39+
## 🎯 问题概述
40+
41+
**当前状态**
42+
- LakeTableSnapshot 完整存储在 ZooKeeper 中
43+
- 包含所有 bucket 的详细信息(log offsets, timestamps, partition info)
44+
- 数据量大,给 ZooKeeper 带来压力
45+
46+
**目标状态**
47+
- **文件系统**:存储完整的 LakeTableSnapshot 对象(大对象)
48+
- **ZooKeeper**:只存储轻量级的 LakeTableSnapshotHandle(小对象,指向文件)
49+
- 保持完全向后兼容
50+
51+
---
52+
53+
## 🏗️ 核心设计
54+
55+
### 新增数据结构
56+
57+
```java
58+
// 轻量级句柄,存储在 ZooKeeper 中
59+
public class LakeTableSnapshotHandle {
60+
private final long snapshotId;
61+
private final long tableId;
62+
private final FsPath metadataFilePath; // 指向文件的路径
63+
64+
public LakeTableSnapshot retrieveLakeTableSnapshot() { ... }
65+
}
66+
```
67+
68+
### 文件存储路径
69+
70+
```
71+
{remote.data.dir}/lake-snapshots/{databaseName}/{tableName}-{tableId}/snapshot-{snapshotId}.json
72+
```
73+
74+
示例:
75+
```
76+
hdfs://namenode/fluss-data/lake-snapshots/default/my_table-123/snapshot-1.json
77+
```
78+
79+
### 版本化格式
80+
81+
- **Version 1** (旧格式): 完整的 LakeTableSnapshot 存储在 ZK
82+
- **Version 2** (新格式): LakeTableSnapshotHandle 存储在 ZK,数据在文件中
83+
84+
### 向后兼容
85+
86+
```java
87+
// 读取时自动识别版本
88+
public Optional<LakeTableSnapshot> getLakeTableSnapshot(...) {
89+
byte[] data = zkClient.getData(path);
90+
int version = parseVersion(data);
91+
92+
if (version == 1) {
93+
return deserializeFromZK(data); // 旧格式
94+
} else if (version == 2) {
95+
LakeTableSnapshotHandle handle = deserializeHandle(data);
96+
return handle.retrieveLakeTableSnapshot(); // 新格式,从文件读取
97+
}
98+
}
99+
```
100+
101+
---
102+
103+
## 📊 文件变更
104+
105+
| 类型 | 文件 | 说明 |
106+
|------|------|------|
107+
| 新增 | `LakeTableSnapshotHandle.java` | 轻量级句柄类 |
108+
| 新增 | `LakeTableSnapshotHandleJsonSerde.java` | 序列化器 |
109+
| 修改 | `FlussPaths.java` | 添加路径工具方法 |
110+
| 修改 | `ZkData.java` | 添加 handle 的 encode/decode |
111+
| 修改 | `ZooKeeperClient.java` | 核心读写逻辑 |
112+
| 修改 | `CoordinatorEventProcessor.java` | 调用新 API |
113+
114+
---
115+
116+
## ⏱️ 工作量评估
117+
118+
**总计:14-21 小时,建议 2-3 天完成**
119+
120+
| 阶段 | 时间 |
121+
|------|------|
122+
| 基础数据结构 | 2-3h |
123+
| 路径工具方法 | 1-2h |
124+
| ZK 客户端修改 | 4-6h |
125+
| Coordinator 修改 | 2-3h |
126+
| 全面测试 | 3-4h |
127+
| 文档和审查 | 2-3h |
128+
129+
---
130+
131+
## 🚀 快速开始
132+
133+
### Step 1: 阅读文档(30 分钟)
134+
```bash
135+
# 按顺序阅读
136+
1. SUMMARY.md # 总览
137+
2. lake-snapshot-migration-design.md # 详细设计
138+
3. implementation-code-examples.md # 代码示例
139+
```
140+
141+
### Step 2: 环境准备(15 分钟)
142+
```bash
143+
# 确认配置
144+
- remote.data.dir 已配置
145+
- 文件系统可访问(HDFS/S3/本地)
146+
- ZooKeeper 可连接
147+
- 开发环境正常
148+
```
149+
150+
### Step 3: 开始编码(按 checklist 执行)
151+
```bash
152+
# 打开实施清单
153+
implementation-checklist.md
154+
155+
# 逐个阶段完成,勾选完成项
156+
# 每个阶段完成后运行测试
157+
```
158+
159+
### Step 4: 提交 PR
160+
```bash
161+
# 确保所有测试通过
162+
mvn clean test
163+
164+
# 创建 PR
165+
git checkout -b feature/issue-2021-lake-snapshot-file-storage
166+
git add .
167+
git commit -m "Move lake snapshot from ZK to file storage"
168+
git push origin feature/issue-2021-lake-snapshot-file-storage
169+
170+
# 在 PR 中关联 Issue #2021
171+
```
172+
173+
---
174+
175+
## ✅ 关键检查点
176+
177+
在提交 PR 前,确保:
178+
179+
- [ ] 所有新增类都有单元测试
180+
- [ ] 所有修改的方法都有测试覆盖
181+
- [ ] 向后兼容性测试通过
182+
- [ ] 集成测试通过
183+
- [ ] 代码覆盖率 > 75%
184+
- [ ] 代码风格检查通过
185+
- [ ] 添加了必要的日志
186+
- [ ] 更新了相关文档
187+
188+
---
189+
190+
## 🤝 需要帮助?
191+
192+
1. **查看代码示例**`implementation-code-examples.md` 有完整的代码
193+
2. **参考现有实现**:查看 KV Snapshot 的实现
194+
- `CompletedSnapshotHandle.java`
195+
- `CompletedSnapshotStore.java`
196+
- `ZooKeeperCompletedSnapshotHandleStore.java`
197+
3. **在 Issue 中提问**https://github.com/apache/fluss/issues/2021
198+
199+
---
200+
201+
**祝你实现顺利!💪🚀**
202+

0 commit comments

Comments
 (0)