RSS

宣布 Flatbuffers 序列化库原生支持 gRPC

Flatbuffers 1.7 版本 最近发布,原生支持 gRPC 的零拷贝功能。

Flatbuffers 是一个序列化库,允许您直接访问序列化数据,而无需先解包或分配任何额外的数据结构。它最初是为游戏和其他资源受限的应用程序设计的,但现在正在得到更广泛的应用,Google 内部团队以及 Netflix 和 Facebook 等其他公司都在使用它。

Flatbuffers 通过对常见用例直接使用 gRPC 的切片缓冲区并进行零拷贝,实现了最大吞吐量。传入的 RPC 可以直接从 gRPC 的内部缓冲区处理,而构建新消息时会直接写入这些缓冲区,无需中间步骤。

这目前在 FlatBuffers 的 C++ 实现中得到完全支持,后续将支持更多语言。Go 中也有一个实现,它并非完全零拷贝,但在分配成本上仍然非常低(见下文)。

使用示例

让我们看一个这如何工作的示例。

使用 Flatbuffers 作为 IDL

从一个 .fbs 模式(如果您熟悉 protocol buffers,它类似于 .proto)开始,该模式声明一个 RPC 服务

table HelloReply {
  message:string;
}

table HelloRequest {
  name:string;
}

table ManyHellosRequest {
  name:string;
  num_greetings:int;
}

rpc_service Greeter {
  SayHello(HelloRequest):HelloReply;
  SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
}

要从此模式生成 C++ 代码,运行:flatc --cpp --grpc example.fbs,就像在 protocol buffers 中一样。

生成的服务器实现

服务器实现与 protocol buffers 非常相似,只是现在请求和响应消息的类型是 flatbuffers::grpc::Message<HelloRequest> *。与 protocol buffers 不同,在 protocol buffers 中这些类型表示 C++ 对象的树,而在这里它们仅仅是底层 gRPC 切片中扁平对象的句柄。您可以直接访问数据

auto request = request_msg->GetRoot();
auto name = request->name()->str();

构建响应同样简单

auto msg_offset = mb_.CreateString("Hello, " + name);
auto hello_offset = CreateHelloReply(mb_, msg_offset);
mb_.Finish(hello_offset);
*response_msg = mb_.ReleaseMessage<HelloReply>();

客户端代码与 protocol buffers 生成的代码相同,只是访问 FlatBuffer 和构建代码不同。

查看完整示例此处。要编译它,您需要 gRPC。同一个仓库中还有一个针对 Go 的类似示例

阅读更多关于如何在您的平台上使用和构建 FlatBuffers 的信息,请访问flatbuffers 网站