Cap'n Proto: Покусочная запись большого сообщения на диск

Я хочу создать гигантский упакованный массив данных и сохранить его на диске. Я использую writePackedMessageToFd(). Однако, поскольку входные данные настолько велики (50 ГБ), мне нужно записать части сообщения на диск, чтобы освободить память.

Возможно ли это с текущей версией Cap'n Proto?

Боковое примечание: этот вопрос отличается от упомянутого повторяющегося вопроса тем, что вывод не нужно передавать в потоковом режиме, например. теоретически могут быть другие варианты, такие как растущий файл, который содержит все (незавершенное) сообщение при первом проходе. И второй проход может закончить сообщение.


person benjist    schedule 10.02.2016    source источник
comment
Меня интересует закрытое голосование. Хотите уточнить?   -  person benjist    schedule 10.02.2016
comment
Моды - это ерунда. Вопрос/ответ помог мне.   -  person Rubber Duck    schedule 11.03.2016


Ответы (1)


То, что вы описываете, скорее всего, не сработает. При чтении упакованного сообщения с диска вы должны прочитать и распаковать все сообщение заранее, что потребует достаточного объема физической оперативной памяти для хранения всего распакованного сообщения.

У вас есть два варианта:

  1. Разбейте сообщение на множество частей. Сообщения Cap'n Proto являются саморазграничивающими, поэтому вы можете записывать несколько сообщений в файл один раз за раз, а затем читать их по одному в том же порядке.

  2. Не используйте упакованный формат. Если сообщение не упаковано, вы можете mmap() его. Затем операционная система будет считывать части в память по мере обращения к ним и при необходимости может сбрасывать их обратно из памяти. В этом случае чтение тривиально, а вот запись в файл изначально сложна. Предположительно, процессу записи файла тоже не хватает места в памяти для всего файла. Cap'n Proto в настоящее время не поддерживает запись через mmap (запись mmap проблематична), но обычно есть еще одна хитрость, которую вы можете сделать: возможно, большие фрагменты вашего сообщения на самом деле происходят непосредственно из некоторых входных файлов, т. е. сообщение содержит огромный байт. blobs из других файлов. В этом случае вы можете использовать mmap() в каждом из этих файлов, а затем включить их в сообщение, используя capnp::Orphanage::referenceExternalData(). Таким образом, файлы не должны одновременно находиться в памяти; ОС будет последовательно вводить и выводить каждую из них по мере записи окончательного вывода. Дополнительную информацию и пример кода см. в этом ответе.

person Kenton Varda    schedule 11.02.2016