fastblock 介绍
高可用性与一致性:通过 Raft 协议确保系统的一致性和高可用性。 低延迟 IO:采用 SPDK 用户态 NVMe 驱动和无锁队列等技术,降低 IO 路径的延迟。 高效网络通信:利用 RDMA 网卡实现零拷贝、内核旁路及无需 CPU 干预的网络通信。
fastblock 架构
主要由以下六部分组成:
1.Monitor
负责节点管理、卷管理、存储卷元数据、集群拓扑结构维护、pg分布管理等工作。Monitor 使用 etcd 进行多副本存储,是系统一致性的关键。它保证客户端和 OSD 看到相同的视图。客户端的 IO 操作只能在 PG 层面进行,而 OSD 和客户端会定期从 Monitor 获取 OSDMap 和 PGMap 信息,确保它们在启动后能同步查看到相同的 PG 状态变化。针对特定 PG 的写入操作,能够避免错误的写入位置。
2.RPC
RPC 子系统是连接各模块的关键组件,支持两种通信方式:
基于 Socket:经典的 Linux Socket,用于 Monitor 与 OSD 之间的通信。
基于 RDMA:利用异步 RDMA 语义进行通信,主要用于 OSD 之间以及 OSD 与客户端之间的通信。
上图是fastblock中各个模块之间的联系,其中使用了三种类型的rpc,分别是Control
Rpc、Data Rpc和Raft Rpc,其用途如下:
Control Rpc:用于客户端与 Monitor、OSD 与 Monitor 之间传递如 OSDMap、PGMap 和镜像信息等小数据量、低频率的操作。由于数据量不大,频率较低,可以使用基于 Socket 的实现。
Data Rpc:用于客户端与 OSD 之间传输对象数据操作和结果。这些数据量较大且频率较高,因此采用基于 RDMA 的通信方式,保证高效的数据传输。
Raft Rpc:用于 OSD 之间传输 Raft 协议内容,内部包含对象数据。这些数据量大、频率高,同样使用基于 RDMA 的方式进行高效传输。
Data RPC和Raft RPC都使用 Protobuf RPC 框架,网络交互部分的代码实现基于 RDMA,而 RPC 传输的数据序列化则使用 Protobuf 格式。
3.OSD Raft
fastblock 使用Raft 协议实现高可用的一致性。Raft 协议通过选举一个领导者(Leader)来管理日志条目(Log Entry)的生成、存储和同步。具体流程包括:领导者接收客户端的数据生成日志条目,将日志写入磁盘并同步给其他副本,指示其他节点何时可以安全地将日志应用到状态机中。
我们自己实现了multi-raft,主要涉及以下几个任务::
raft groups管理,包括raft的创建、修改和删除
raft选举以及选举超时处理
raft log处理,包括log缓存、log落盘和log复制到follower节点
数据state machine处理,既数据落盘
raft快照管理和raft数据恢复
raft成员变更管理
raft心跳合并
在multi-raft设计中,会有多个raft并存,每个 Raft 组的 Leader 都需要定期发送心跳包(heartbeat)到其 Follower。如果 Raft 过多,会导致心跳包数量过多,进而占用大量带宽和 CPU 资源。为了解决这一问题,我们对相同 Leader 和相同 Follower 的 Raft 组进行心跳包的合并。
心跳合并示例:假设有两个 PG(PG1 和 PG2),PG1 和 PG2 中都包含 OSD1、OSD2 和 OSD3,且 OSD1 为 Leader。OSD1 需要向 OSD2 和 OSD3 都发送两个心跳包(PG1的heartbeat和PG2的heartbeat)。
在心跳合并机制下,OSD1 只需要向OSD2 和 OSD3 分别发送一个合并后的心跳包,包含 PG1 和 PG2 的心跳,从而减少了不必要的心跳包数量,优化了带宽和 CPU 资源的使用。
4.OSD KV
5.OSD localstore
disk_log:存储raft log的数据,一个pg对应一个spdk blob object_store: 存储对象数据,一个对象对应一个spdk blob kv_store: 每个cpu核有一个spdk blob,保存当前cpu核上需要保存到磁盘的所有kv数据。
6.客户端
使用spdk vhost提供给虚拟机 使用NBD提供给裸金属 使用spdk nvmf-tgt,通过操作系统内核导出磁盘