Below you will find pages that utilize the taxonomy term “linux 文件系统 性能”
Posts
微信 phxpaxos 源码解读:fsync 和 fdatasync
最近在读微信开源的 paxos 实现 phxpaxos,读到 localstorage 部分学习到 fdatasync 系统调用。这一部分是非常核心的存储模块,参与者的状态信息、变更日志等都要写入磁盘并且可能要求强制刷入存储磁盘避免系统崩溃等情况下数据丢失,性能的很大一部分因素取决于这一块的实现。
phxpaxos 使用了 LevelDB 做存储,但是做了几个优化:
LevelDB 存储的 value 只是一个 24 个字节的 fileid 索引(有一个例外 minchosen 值),真正的状态数据存储在他们自己实现的 log_store 里, fileid 存储了在 log_store 里的文件编号、写入 vfile 的offset 和 checksum 这三个字段信息。这样做的原因是由于 leveldb 对于比较大的 value 的存取效率不是最优,通过间接一层存储,利用了 LevelDB 的 Key 的有序性和小 value 存储的性能优势,加上定制的 log_store 的写入优化,达到最优组合。 log_store 按照文件编号固定增长,比如 1.f、2.f、3.f ……以此类推(在日志目录的 vfile 目录下)。并且每个文件都是在创建的时候分配固定大小,默认 100M(还有所谓 large buffer 模式分配的是 500M)。值的写入都是 append 操作,写入完成后,将偏移量、校验和、当前文件 ID 再写入 LevelDB。读取的时候就先从 LevelDB 得到这三个信息,然后去对应的 vfile 读取实际的值。因为文件是固定大小分配,每次强制刷盘就不需要调用 fsync,而是采用 fdatasync,这样就无需做两次刷盘,因为 fdatasync 不会去刷入文件的元信息(比如大小、最后访问时间、最后修改时间等),而 fsync 是会的。 一张图来展示大概是这样: