为啥 protobuf 不适合大型数据结构?

Posted

技术标签:

【中文标题】为啥 protobuf 不适合大型数据结构?【英文标题】:Why protobuf is bad for large data structures?为什么 protobuf 不适合大型数据结构? 【发布时间】:2017-11-30 01:18:36 【问题描述】:

我是 protobuf 的新手。我需要序列化复杂的类图结构并在 C++ 和 Python 客户端之间共享。 我正在尝试应用 protobuf,因为:

它与语言无关,具有 C++ 和 Python 的生成器 它是二进制的。我买不起文本格式,因为我的数据结构很大

但 Protobuf 用户指南说:

协议缓冲区不是为处理大消息而设计的。作为一个 一般经验法则,如果您处理的消息大于 每兆字节,可能是时候考虑另一种策略了。

https://developers.google.com/protocol-buffers/docs/techniques#large-data

我的图形结构有时高达 1 Gb,远高于 1 Mb。

为什么 protobuf 不适合序列化大型数据集?我应该改用什么?

【问题讨论】:

【参考方案1】:

这只是一般指导,因此并不适用于所有情况。例如,OpenStreetMap 项目为其地图使用基于协议缓冲区的文件格式,文件大小通常为 10-100 GB。另一个例子是谷歌自己的 TensorFlow,它使用 protobuf,它存储的图形通常高达 1 GB。

但是,OpenStreetMap 不会将整个文件作为一条消息。相反,它由数千条单独的消息组成,每条消息都对地图的一部分进行编码。您可以应用类似的方法,以便每条消息仅编码例如一个节点。

用于大文件的 protobuf 的主要问题是它不支持随机访问。即使您只想访问特定项目,您也必须阅读整个文件。如果您的应用程序无论如何都会将整个文件读取到内存中,那么这不是问题。这就是 TensorFlow 所做的,它似乎将所有内容都存储在一条消息中。

如果您需要一种兼容多种语言的随机访问格式,我建议您使用 HDF5 或 sqlite。

【讨论】:

谢谢,从文件中随机存取对我来说不是问题,我可以将 1gb 预加载到内存中。 The main problem with protobuf for large files is that it doesn't support random access. 这就是 TensorFlow lite 使用 Flat Buffers 而不是 Protobufs 的原因。 FlatBuffersrepresents hierarchical data in a flat binary buffer。移动设备的内存要少得多,只能反序列化模型文件以读取元数据。【参考方案2】:

使用远大于 1MB 的协议缓冲区应该没问题。我们在 Google 一直这样做,我什至不知道您引用的建议。

主要问题是您需要一次将整个协议缓冲区反序列化到内存中,因此值得考虑将数据分解成更小的项目是否更好,这样您只需拥有部分数据立即进入内存。

如果你不能打破它,那就不用担心。继续使用大量的协议缓冲区。

【讨论】:

以上是关于为啥 protobuf 不适合大型数据结构?的主要内容,如果未能解决你的问题,请参考以下文章

ProtoBuf简介

protobuf适不适合物联网

用 protobuf 替换 binaryformatter

protobuf-net 不适合哪些场景?

用于不适合内存的大型 hdf5 文件的 Keras 自定义数据生成器

ProtoBuf系列protobuf的介绍与安装