1.Seafile 存储模型探索
Seafile 存储模型探索
Seafile是码安一个国内开源的网盘产品,具备社区版与专业版。码安在网盘类产品的码安研发过程中,对其部分源码进行了研究。码安Seafile采用类似于Git的码安模型进行文件存储,涉及几个关键概念。码安drcom go源码
Repo作为资料库,码安相当于一个存储盘,码安每个Repo创建时,码安会在Repo表中插入一条记录。码安Branch类似于Git中的码安分支,每个Repo默认包含一条master分支。码安
Commit相当于Git中的码安提交记录,每次文件上传或修改都会产生新的码安commit,并通过上图展示,码安以太坊 源码master分支指向最新commit。通过branch的head commit和每条commit记录的parent_id,可以将所有提交记录按顺序串联。
Seafile没有采用MySQL存储commit和file元数据,而是直接将这些元数据以JSON文本形式存储至文件系统中。打开Seafile存储目录,可见三个主要文件夹:blocks、盗版源码commits、fs。
blocks文件夹用于存储文件真实数据,采用CDC算法进行分块存储。commits文件夹存储repo的commit记录,每条commit对应一个文件,内容为commit数据结构的半源码json字符串。fs文件夹存储repo中目录层级信息及文件信息,所有目录信息在fs目录下打平,文件层级关系通过fs文件内容表达。
在对commit记录分析中,每次repo变动生成新commit并写入commits文件夹。通过commit id定位文件,打开可见json文本内容,拆源码记录commit相关信息,如parent_id、root_id等。parent_id指向上一次commit id,通过branch head commit和各commit记录parent_id,可串联所有提交记录。
fs记录每次commit的快照信息,根据最新commit id定位fs目录,找到对应root_id的json文本。文本记录根目录下的文件信息,表示根目录及子目录文件结构。通过root_id定位目录元数据文件,查看内容,了解子目录及文件信息。
blocks记录文件数据块,以某个文件为例,通过commit id定位到block文件,查看内容为文件所有数据块id,对应blocks目录下的文件。
整体存储结构展示了文件树的构建过程。新建文件夹或上传文件后,commit记录更新,fs快照生成,blocks数据块存储。这种设计支持快速回滚到某版本,同时具备多端同步特性,但每次修改单个文件时,需生成所有祖先节点版本,造成写放大,深目录层级情况下需考虑性能损耗。