OneArchive - 场景分析文档
1. 系统初始化场景
1.1. 首次运行程序
系统在首次运行时需要完成以下初始化步骤:
- 创建配置文件
- 初始化数据库索引表
- 扫描指定目录并建立文件索引
- 根据文件修改时间策略(如 30 分钟未修改的文件)进行初次归档
- 将频繁修改的文件暂存到临时目录
1.2. 程序重启/后续运行
系统在重启或后续运行时执行以下流程:
- 读取配置文件
- 加载数据库索引表
- 重新扫描文件系统并对比文件列表
- 更新索引表以反映文件系统变化
- 将满足归档条件的文件添加到归档中
- 可选:执行压缩或加密操作
2. 核心业务场景
2.1. 归档场景
用户指定目录进行归档的完整流程:
- 用户提供待归档的目录路径
- 系统检查目录是否已存在归档列表中:
- 若已存在,则执行增量归档(仅处理新增或变更文件)
- 若不存在,则创建新的归档任务
- 系统创建索引表并开始归档过程
2.1.1. 文件处理策略
- 大文件处理:对于超过归档限制的文件(如 100G 文件),系统采用分卷存储策略
- 文件变化处理:系统需要处理归档过程中文件变化的情况,避免数据不一致
- 文件去重:基于文件内容哈希进行智能去重
2.1.2. 分卷存储机制
系统在以下情况下对文件进行分卷存储:
- 单个文件大小超过归档限制
- 归档卷达到预设大小限制
系统维护以下关键变量:
- 归档限制体积
- 当前归档卷大小
- 归档卷编号
分卷文件命名规则推荐:archive_001.tar
2.2. 解档场景
用户从归档中提取文件的完整流程:
- 用户从归档目录列表中选择需要解档的归档
- 用户指定解档目标目录
- 系统还原目录树结构,并将归档中的文件恢复到目标目录
2.3. 多设备/多目录解档场景
支持将归档文件解档到多个设备或目录的配置需求,需要设计相应的配置文件结构来支持此场景。
3. 数据库索引与文件操作场景
3.1. 查询指定路径场景
对外仅暴露查询接口,不暴露实现逻辑。查询路径的实现方式如下:
3.1.1. 阶段 1 实现
布隆过滤器 A (存放所有被添加过的完整路径) -> dir_index 表 > 完整相对路径
3.1.2. 阶段 2 实现
布隆过滤器 A (存放所有被添加过的完整路径) -> dir_index 表 > 完整相对路径 + 闭包表
注意:不推荐使用布隆过滤器存放被删除过的路径,因为用户可能撤销了删除,或者重新添加了相同的目录
3.2. 目录操作场景
3.2.1. 创建/添加目录
- dir_index 表,添加一条记录
- 将所有关联的 file 添加到 file_index 表 (详见「场景 - 添加文件」)
3.2.2. 删除目录
- dir_index 表,删除指定目录以及所有子目录
- 将所有关联的 file 标记为回收状态
3.2.3. 移动目录
由于 dir_index, file_index 仅仅是索引表,他们的变更并不会影响实际的物理文件变化,所以使用删除 + 添加代替常规的移动,并不会显著影响性能
- dir_index 表,删除目录
- dir_index 表,添加目录
3.3. 文件操作场景
3.3.1. 添加文件 (体积<archive_size)
3.3.1.1. 渐进式开启 hash
- 在 file_index 表中添加文件索引
- 在 archive_content 表中查找是否有相同 mtime + size 的文件
- 如果存在相同的文件,则计算文件 hash
- 添加文件 hash 到 file_index 表中
- 如果 mtime + size + hash 都一致,则把 archive_chunk_id 添加到 file_index 表中
3.3.1.2. 保持开启 hash
- 文件计算 hash
3.3.2. 文件归档
说明:参考添加文件的步骤,如果归档中已经存在相同的数据块,则 file_index 表中对应的 archive_chunk_id 会有值,所以 archive_chunk_id 值不为空的文件不需要重新归档。
- 遍历 file_index 表,获取 archive_chunk_id 为空的文件
- 获取文件的完整路径 (此处逻辑抽象,调用者不需要知道是从临时目录,还是原始目录获取的文件)
- 获取文件的元信息
- 计算文件的 hash
- 将文件添加到指定的 archive 中
- [Q]添加到指定的 archive 的过程中,程序中断
- 在 archive_chunk 表中添加 chunk 记录
- 更新 file_index 表中 archive_chunk_id 的值
3.3.3. 回收文件
- 将文件标记为回收状态,但保留数据直到实际清理
3.3.4. 文件的物理删除
即从 archive_content 表中删除,当且仅当归档清理时才执行 而归档清理,和文件归档解档操作是逻辑互斥的,所以不需要担心文件归档操作到一半,归档内容被删除。