zl程序教程

您现在的位置是:首页 >  Java

当前栏目

Polardb 核心存储 polarfs 是怎么进行数据存储的之核心构造(4)--译

2023-02-18 16:28:13 时间

关于POLARDB 的数据存储部分的论文翻译还在继续,此为第四部分,与IO 的实现有关_________________________________________________________________

4. I/O EXECUTION MODEL

当POLARDB 需要读取数据的情况下,他会通过PFS 接口提交IO的需求给我们的libpfs,通常pfs_pread 或者 pfs_pwrite来完成这个客户的请求,对于写的需求,这里大部分的需求是不需要对数据的METADATA 进行修改的,所以也就不需要去为设备的块来通过pfs_fallocate 来分配操作到文件。因此避免了昂贵的 meta data 同步写和读。

在大多数常见情况下,libpfs只是根据挂载时已经构建的索引表将文件偏移量映射到块偏移量,并将文件I/O请求切成一个或多个较小的固定大小的块I/O请求。转换完成后,块请求通过libpfs 通过shared memory 发送到polarswitch。

这里共享内存被设置为环形,在共享内存的一端libpfs 将需求插入到环形的内存中,并进行处理,直到这些需求被完成。在另一端,PolarSwitch不断轮询所有环形缓冲区,有一个线程专门用于环形缓冲区。一旦发现了新的请求,PolarSwitch就会从环形缓冲区中将请求从队列中解出,并将它们与从PolarCtrl传播的路由信息一起转发给chunkserver。

Chunkserver使用预写日志(write ahead logging, WAL)技术来确保原子性和持久性,在这种技术中,I/O请求在提交和应用之前被写入日志。日志被复制到一个副本集合中,并使用名为ParallelRaft的协议来,保证副本之间的数据一致性。IO的写需求被急流到多个副本中,如果没有完成这个工作,是不会被识别为已提交的状态,客户应用数据也必须在这个需求被应用后才能读取和使用。

图四,中展示了写IO request在POLARDB 内部是怎么执行的

1 POLARDB 发送一个写请求在polarswitch 和 libpfs 之间,polarswitch 通过环形buffer来完成工作。

2 POLARSWTICH 传输request 到对应的chunk's leader 节点,依据本地的缓冲的集群元数据。

3 当新的写请求到达时,leader节点中的RDMA网卡将把写请求放入缓冲区中,并在请求队列中添加一个请求条目。I/O循环线程持续轮询请求队列。一旦它看到一个新的请求到达,它就会立即开始处理这个请求。

4 需求被通过spdk 写入到磁盘上的日志块,通过RDMA将信息传递到其他的从节点,两个操作实际上是并行的异步出的方式。

5 当数据复制需求传输到从节点后,RDMA NIC 会将写需求放入到预写buffer,并且将其添加到复制的队列中

6 然后IO loop thread 在从节点被触发,并且写请求通过SPDK 异步写入到磁盘

7 当写入成功并回馈的后,一个响应的请求通过RDMA发送到主节点

8 当主节点接受来自从节点的回馈,并确认写入成功后,将引入本地写,通过SPDK写入。

9 此后 LEADER 节点通过rdma 来应用POLARSWTICH 的信息。

10 POLARSWITCH 标记了相关的写需求完毕,并告知客户

读I/O请求由leader单独处理。在ChunkServer中有一个名为IoScheduler的子模块,它负责仲裁由并发I/O请求,发出的磁盘I/O操作是有操作顺序的,并在ChunkServer上执行。IoScheduler保证读操作总是可以检索最新提交的数据。

ChunkServer使用轮询模式和事件驱动的有限状态机作为并发模型。I/O线程保持来自RDMA和NVMe队列的轮询事件,在同一个线程中处理传入的请求。当发出一个或多个异步I/O操作并需要处理其他请求时,I/O线程将暂停处理当前请求并将上下文保存到状态机中,然后切换到处理下一个传入事件。

ChunkServer使用轮询模式和事件驱动的有限状态机作为并发模型。I/O线程来自RDMA和NVMe队列的轮询事件,在同一个线程处理传入的请求。当发出一个或多个异步I/O操作并需要处理其他请求时,I/O线程将暂停处理当前请求并将上下文保存到状态机中,然后切换到处理下一个传入事件。

每个I/O线程使用一个专用的核心,并使用分离RDMA和NVMe队列对。所以这里对于IO并没有锁定,也没有锁开销,即使单个CHUNKSERVER上有多个IO线程的情况下,主要的原因为I/O线程之间没有共享数据结构。

此篇看上去比较枯燥,实际上是比较重要的这篇主要描述的是数据在POLARDB 底层的数据传输以及数据的落盘和反馈的过程。