我想创建一个巨大的打包数据数组,并将其保存在磁盘上。我正在使用 writePackedMessageToFd()。但是,由于输入数据如此之大(50GB),我需要将消息片段存储到磁盘以释放内存。
当前版本的 Cap'n Proto 可以做到这一点吗?
旁注:这个问题与提到的重复问题不同,因为输出不需要流式传输,例如理论上可能有其他选项,例如在第一遍中保存整个(未完成)消息的增长文件。第二遍可以完成消息。
完全按照您的描述可能行不通。从磁盘读取打包的消息时,您必须预先读取并解包整个消息,这将需要足够的物理 RAM 来保存整个解包的内容。
你有两个选择:
将消息分成许多块。Cap'n Proto 消息是自定界的,因此您可以一次将多条消息写入一个文件,然后以相同的顺序一次读回一条。
不要使用打包格式。如果消息没有打包,那么你可以mmap()
。然后,操作系统将在访问部分时将其读入内存,并可以在以后根据需要将它们从内存中刷新出来。在这种情况下,读取是微不足道的,但最初写入文件却很棘手。据推测,写入文件的进程在内存中也没有整个文件的空间。Cap'n Proto 目前不支持通过 mmap 写入(可写 mmap 存在问题),但通常还有另一个技巧可以做:可能,您的消息的大块实际上直接来自某些输入文件,即消息嵌入了巨大的字节来自其他文件的 blob。在这种情况下,您可以 mmap() 在每个文件中,然后您可以使用将它们合并到消息中capnp::Orphanage::referenceExternalData()
. 这样,文件不必同时都驻留在内存中;在写入最终输出时,操作系统将按顺序分页和分页。有关更多详细信息和一些示例代码,请参阅此答案。