跳到主要内容
版本:0.14

行格式

Apache Fory™ 提供高性能的行格式以实现零拷贝反序列化。

概述

与在内存中重构完整对象的传统对象序列化不同,行格式支持直接从二进制数据随机访问字段,无需完整反序列化。

主要优势:

  • 零拷贝访问:无需分配或复制数据即可读取字段
  • 部分反序列化:仅访问所需的字段
  • 内存映射文件:处理大于 RAM 的数据
  • 缓存友好:顺序内存布局以提高 CPU 缓存利用率
  • 延迟计算:将昂贵的操作延迟到字段访问时

何时使用行格式

  • 具有选择性字段访问的分析工作负载
  • 仅需要字段子集的大型数据集
  • 内存受限环境
  • 高吞吐量数据管道
  • 从内存映射文件或共享内存读取

基础用法

use fory::{to_row, from_row};
use fory::ForyRow;
use std::collections::BTreeMap;

#[derive(ForyRow)]
struct UserProfile {
id: i64,
username: String,
email: String,
scores: Vec<i32>,
preferences: BTreeMap<String, String>,
is_active: bool,
}

let profile = UserProfile {
id: 12345,
username: "alice".to_string(),
email: "alice@example.com".to_string(),
scores: vec![95, 87, 92, 88],
preferences: BTreeMap::from([
("theme".to_string(), "dark".to_string()),
("language".to_string(), "en".to_string()),
]),
is_active: true,
};

// 序列化为行格式
let row_data = to_row(&profile);

// 零拷贝反序列化 - 无对象分配!
let row = from_row::<UserProfile>(&row_data);

// 直接从二进制数据访问字段
assert_eq!(row.id(), 12345);
assert_eq!(row.username(), "alice");
assert_eq!(row.email(), "alice@example.com");
assert_eq!(row.is_active(), true);

// 高效访问集合
let scores = row.scores();
assert_eq!(scores.size(), 4);
assert_eq!(scores.get(0), 95);
assert_eq!(scores.get(1), 87);

let prefs = row.preferences();
assert_eq!(prefs.keys().size(), 2);
assert_eq!(prefs.keys().get(0), "language");
assert_eq!(prefs.values().get(0), "en");

工作原理

  • 字段在二进制行中编码,原始类型使用固定偏移量
  • 变长数据(字符串、集合)使用偏移指针存储
  • Null 位图跟踪哪些字段存在
  • 通过递归行编码支持嵌套结构

性能比较

操作对象格式行格式
完整反序列化分配所有对象零分配
单字段访问需要完整反序列化直接偏移读取
内存使用内存中的完整对象图仅已访问字段在内存中
适用于小对象,完整访问大对象,选择性访问

ForyRow vs ForyObject

功能#[derive(ForyRow)]#[derive(ForyObject)]
反序列化零拷贝,延迟完整对象重构
字段访问直接从二进制正常结构体访问
内存使用最小完整对象
最适合分析,大数据通用序列化

相关主题