新一代日志型系统在 SOFAJRaft 中的应用

本文介绍了基于SOFAJRaft的高性能Java日志系统改进,移除对RocksDB的依赖,设计了纯Java的索引模块,涉及内存映射、文件管理、组提交和预分配技术,旨在提升存储性能和代码可读性。

在这里插入图片描述

📄

文|黄章衡(SOFAJRaft 项目组)

福州大学 19 级计算机系

研究方向|分布式中间件、分布式数据库

Github 主页|https://github.com/hzh0425

校对|冯家纯(SOFAJRaft 开源社区负责人)

本文 9402 字 阅读 18 分钟

PART. 1 项目介绍

1.1 SOFAJRaft 介绍

SOFAJRaft 是一个基于 RAFT 一致性算法的生产级高性能 Java 实现,支持 MULTI-RAFT-GROUP,适用于高负载低延迟的场景。使用 SOFAJRaft 你可以专注于自己的业务领域,由 SOFAJRaft 负责处理所有与 RAFT 相关的技术难题,并且 SOFAJRaft 非常易于使用,你可以通过几个示例在很短的时间内掌握它。

Github 地址:

https://github.com/sofastack/sofa-jraft

img

1.2 任务要求

**目标:*当前 LogStorage 的实现,采用 index 与 data 分离的设计,我们将 key 和 value 的 offset 作为索引写入 rocksdb,同时日志条目(data)*写入 Segment Log。因为使用 SOFAJRaft 的用户经常也使用了不同版本的 rocksdb,这就要求用户不得不更换自己的 rocksdb 版本来适应 SOFAJRaft, 所以我们希望做一个改进:移除对 rocksdb 的依赖,构建出一个纯 Java 实现的索引模块。

PART. 2 前置知识

Log Structured File Systems

如果学习过类似 Kafka 等消息队列的同学,对日志型系统应该并不陌生。

如图所示,我们可以在单机磁盘上存储一些日志型文件,这些文件中一般包含了旧文件和新文件的集合。区别在于 Active Data File 一般是映射到内存中的并且正在写入的新文件*(基于 mmap 内存映射技术)*,而 Older Data File 是已经写完了,并且都 Flush 到磁盘上的旧文件,当一块 Active File 写完之后,就会将其关闭,并打开一个新的 Active File 继续写。

img

并且每一次的写入,每个 Log Entry 都会被 Append 到 Active File 的尾部,而 Active File 往往会用 mmap 内存映射技术,将文件映射到 os Page Cache 里,因此每一次的写入都是内存顺序写,性能非常高。

终上所述,一块 File 无非就是一些 Log Entry 的集合,如图所示:

img

同时,仅仅将日志写入到 File 中还不够,因为当需要搜索日志的时候,我们不可能顺序遍历每一块文件去搜索,这样性能就太差了。所以我们还需要构建这些文件的 “目录”,也即索引文件。这里的索引本质上也是一些文件的集合,其存储的索引项一般是固定大小的,并提供了 LogEntry 的元信息,如:

- File_Id : 其对应的 LogEntry 存储在哪一块 File 中

- Value_sz : LogEntry 的数据大小

(注: LogEntry 是被序列化后, 以二进制的方式存储的)

- Value_pos: 存储在对应 File 中的哪个位置开始

- 其他的可能还有 crc,时间戳等…

img

那么依据索引文件的特性,就能够非常方便的查找 IndexEntry。

- 日志项 IndexEntry 是固定大小的

- IndexEntry 存储了 LogEntry 的元信息

- IndexEntry 具有单调递增的特性

举例,如果要查找 LogIndex = 4 的日志:

- 第一步,根据 LogIndex = 4,可以知道索引存储的位置:IndexPos = IndexEntrySize * 4

- 第二步,根据 IndexPos,去索引文件中,取出对应的索引项 IndexEntry

- 第三步,根据 IndexEntry 中的元信息,如 File_Id、Pos 等,到对应的 Data File 中搜索

- 第四步,找到对应的 LogEntry

img

内存映射技术 mmap

上文一直提到了一个技术:将文件映射到内存中,在内存中写 Active 文件,这也是日志型系统的一个关键技术,在 Unix/Linux 系统下读写文件,一般有两种方式。

传统文件 IO 模型

一种标准的 IO 流程, 是 Open 一个文件

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值