Возможно ли, чтобы каналы сбрасывали данные на диск?

Вопрос или проблема

Есть ли какие-либо установленные инструменты, которые позволяют записывать данные на диск, а не блокировать процесс выше по потоку?

В качестве примера, в традиционном конвейере A | B, мы получаем следующий порядок действий, когда B не читает из stdin:

  • A выдает вывод, пока stdout не заполняется
  • Затем A блокируется, пока B не прочтет из stdin

Я хотел бы получить следующий порядок действий:

  • A выдает вывод, пока его буфер stdout не заполнится
  • Дальнейший вывод от A записывается в кэш-файл на диске, так что A не блокируется
  • Когда B получает данные из stdin, новые данные из кэш-файла на диске читаются (FIFO) в буфер

Существуют ли какие-либо инструменты, которые выполняют это?

Спасибо!

То, что вы описываете, — это “буфер”, а не “кэш”.

С помощью утилиты mbuffer:

producer | mbuffer -t -m 10G | consumer

Это приведет к тому, что mbuffer будет использовать файл с отображением в памяти (опция -t), чтобы буферизовать потенциально большое количество данных, которые выводит producer, если consumer не может читать их достаточно быстро. Размер файла с отображением в памяти будет ограничен 10 ГБ (если этот файл заполнится, mbuffer будет блокироваться как обычно).

Ответ или решение

Да, существует возможность реализации такого поведения, о котором вы говорите, и существует несколько инструментов для выполнения этой задачи. В вашем случае действительно речь идет о "буфере", который может временно хранить данные на диске, не блокируя при этом процесс, производящий данные.

Как это работает

В традиционной модели обработки данных по конвейеру, когда команда A передает вывод через | в команду B, возникает определенная проблема: если B не читает из стандартного ввода, тогда A блокируется, пока B не станет доступен. Эта блокировка происходит потому, что системные буферы заполнены, и операции записи не могут быть завершены. Однако вы хотите избежать этой блокировки, позволяя данным временно сохраняться на диске.

Решение с использованием mbuffer

Одним из наиболее известных и широко используемых инструментов для решения этой проблемы является mbuffer. Этот инструмент позволяет вам создать буферизацию на уровне процесса с возможностью записи данных на диск.

Пример использования

Команда, которую вы можете использовать для реализации буферизации с использованием mbuffer, выглядит так:

producer | mbuffer -t -m 10G | consumer

В этом примере:

  • producer — это ваш первый процесс, который генерирует данные.
  • mbuffer -t -m 10G — это команда, которая создает мутабельный буфер, который можно настроить для использования файла, размещаемого в памяти, при этом ограничение составляет 10 ГБ. Это значит, что, если consumer не способен обрабатывать данные достаточно быстро, mbuffer будет продолжать принимать данные от producer и хранить их в своём временном хранилище. Если файл заполнится, начнется стандартная блокировка.
  • consumer — это ваш второй процесс, который читает данные.

Другие инструменты

Существуют и другие инструменты, обеспечивающие аналогичную функциональность:

  1. pv (Pipe Viewer): Этот инструмент позволяет вам видеть прогресс передачи данных и может использовать временные файлы для хранения данных, если происходит блокировка.

  2. tee с использованием временных файлов: Хотя это решение менее элегантно, tee может использоваться в комбинации с файловыми операциями для временного хранения данных, но потребуется больше конфигураций и дополнительных скриптов.

Заключение

Ваш взгляд на проблему — это важный шаг к оптимизации потоковой обработки данных в UNIX-подобных системах. Использование инструментов, таких как mbuffer, значительно облегчает задачи по буферизации данных и позволяет избежать ненужных блокировок, улучшая общую эффективность процессов. Таким образом, вы можете добиться желаемого поведения и обеспечить более плавную работу ваших конвейеров обработки данных.

Оцените материал
Добавить комментарий

Капча загружается...