SeaStore 硬盘存储调用机制
1. 概述
SeaStore 通过多层抽象来访问底层存储设备,最终使用 Seastar 框架的 DMA(Direct Memory Access)接口进行实际的 I/O 操作。本文档详细说明从应用层到硬件层的完整调用路径。
2. 调用层次结构
1 | 应用层 (SeaStore API) |
3. 设备抽象层
3.1 Device 接口
位置: device.h
Device 是存储设备的抽象接口,定义了统一的读写接口:
1 | class Device { |
3.2 设备实现类型
SeaStore 支持两种主要的设备类型:
段式设备 (SEGMENTED):
BlockSegmentManager: 普通块设备ZBDSegmentManager: Zoned Block Device (ZBD)EphemeralSegmentManager: 临时内存设备(测试用)
随机块设备 (RANDOM_BLOCK):
RandomBlockManager: 随机访问块设备
4. 段式设备调用路径
4.1 写入路径
4.1.1 调用链
1 | TransactionManager::submit_transaction() |
4.1.2 关键代码
Segment::write() (segment_manager/block.cc:372):
1 | Segment::write_ertr::future<> BlockSegment::write( |
BlockSegmentManager::segment_write() (segment_manager/block.cc:425):
1 | Segment::write_ertr::future<> BlockSegmentManager::segment_write( |
do_writev() (segment_manager/block.cc:87):
1 | static write_ertr::future<> do_writev( |
4.2 读取路径
4.2.1 调用链
1 | Cache::read_extent() |
4.2.2 关键代码
do_read() (segment_manager/block.cc:137):
1 | static read_ertr::future<> do_read( |
5. Seastar DMA 接口
5.1 文件对象创建
位置: segment_manager/block.cc:258
1 | static open_device_ret open_device(const std::string &path) |
5.2 DMA 操作特点
- 零拷贝: DMA 操作直接从用户缓冲区传输到内核,减少数据拷贝
- 异步 I/O: 所有操作都是异步的,返回
seastar::future - 对齐要求: 缓冲区和偏移必须满足 DMA 对齐要求
- 批量操作: 支持
writev/readv进行批量 I/O
5.3 Seastar 底层实现
Seastar 的 dma_read/dma_write 最终会调用:
- Linux AIO: 使用
io_submit()和io_getevents()进行异步 I/O - io_uring: 如果系统支持,使用更高效的 io_uring 接口
- 直接 I/O: 绕过页缓存,直接访问存储设备
6. 随机块设备调用路径
6.1 RandomBlockManager
位置: random_block_manager/block_rb_manager.cc
随机块设备也使用类似的 DMA 接口:
1 | RandomBlockManager::write_ertr::future<> |
7. 设备初始化流程
7.1 设备创建
1 | Device::make_device(device_path, device_type) |
7.2 设备挂载
1 | Device::mount() |
8. I/O 优化机制
8.1 批量 I/O
SeaStore 使用 writev/readv 进行批量 I/O 操作:
1 | // 准备多个 I/O 向量 |
8.2 对齐优化
所有 I/O 操作都按照块大小对齐:
1 | // 确保缓冲区对齐 |
8.3 异步 I/O
所有 I/O 操作都是异步的,使用 Seastar 的 future/promise 机制:
1 | return device.dma_write(offset, buffer, len) |
9. 错误处理
9.1 I/O 错误类型
input_output_error: 底层 I/O 错误invarg: 无效参数(如未对齐)enospc: 空间不足erange: 地址超出范围
9.2 错误处理机制
1 | return device.dma_write(offset, buffer, len) |
10. 性能特性
10.1 DMA 优势
- 零拷贝: 数据直接从用户缓冲区传输到设备,无需内核拷贝
- 异步操作: 不阻塞线程,充分利用 CPU
- 批量操作: 支持向量 I/O,减少系统调用次数
10.2 Seastar 优化
- 事件驱动: 基于 epoll/io_uring 的事件驱动模型
- 协程支持: 使用协程简化异步代码
- Shard 隔离: 每个 CPU 核心独立处理 I/O
11. 总结
SeaStore 的存储调用机制具有以下特点:
- 多层抽象: 从 Device 接口到具体实现,再到 Seastar DMA 接口
- 异步 I/O: 所有操作都是异步的,提高并发性能
- 零拷贝: 使用 DMA 减少数据拷贝开销
- 类型支持: 支持段式设备和随机块设备
- 错误处理: 完善的错误处理和恢复机制
通过这种设计,SeaStore 能够充分利用现代存储设备的性能,同时保持代码的清晰和可维护性。