将 oic-cache 的核心数据类型从 Vec<u8> 迁移到 bytes::Bytes,以提升性能并与 Axum 生态系统保持一致。
主要变更
1. 核心类型更新
-
StorageLocation:
Inline(Vec<u8>)→Inline(Bytes) -
API 返回类型:
Option<Vec<u8>>→Option<Bytes> -
API 参数类型:
Vec<u8>→impl Into<Bytes>
2. 存储层优化
-
read_inline(): 返回Bytes,零拷贝 Clone -
read_file(): 返回Bytes,零成本转换 -
compress()/decompress(): 返回Bytes
3. 应用层适配
-
oic-web服务层和控制器层已更新 - 所有测试和示例代码已迁移
性能提升
1. 零拷贝 Clone
之前 (Vec<u8>):
let data = cached_data.clone(); // O(n) 内存复制
现在 (Bytes):
let data = cached_data.clone(); // O(1) 引用计数
收益:
- 内联存储(< 4KB)的 Clone 操作从 O(n) 降至 O(1)
- 缓存命中时的数据传递零拷贝
- 在高并发场景下显著减少内存分配和复制开销
2. 内存效率
-
Bytes使用引用计数,多个引用共享同一份底层数据 - 减少不必要的内存分配
- 降低 GC 压力(虽然 Rust 没有 GC,但减少分配有助于内存管理)
3. 与 Axum 生态一致
- Axum 底层使用
Bytes类型 - 减少类型转换开销(
Vec<u8>→Bytes) - 更好的互操作性
实际场景性能影响
缓存命中场景
- 之前: 每次缓存命中需要复制整个数据(O(n))
- 现在: 仅增加引用计数(O(1))
- 提升: 对于 10KB 的缓存数据,减少约 10KB 的内存复制
并发读取场景
- 之前: 1000 个并发读取 = 1000 次完整数据复制
- 现在: 1000 个并发读取 = 1 次数据分配 + 1000 次引用计数操作
-
提升: 内存使用量从
1000 × data_size降至1 × data_size
内联存储场景
-
之前: 每次
read_inline()返回都需要复制数据 - 现在: 零拷贝返回,多个引用共享同一份数据
- 提升: 小数据(< 4KB)的读取性能提升显著
技术优势
-
零拷贝语义:
Bytes实现了零拷贝的 Clone,适合高并发场景 -
内存共享: 多个
Bytes实例可以共享底层数据,减少内存占用 - 类型安全: 保持强类型,编译时检查
- 生态兼容: 与 Axum、Hyper 等 HTTP 框架原生兼容

bytes.png