Вопрос или проблема
Есть ли какие-либо установленные инструменты, которые позволяют записывать данные на диск, а не блокировать процесс выше по потоку?
В качестве примера, в традиционном конвейере 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
— это ваш второй процесс, который читает данные.
Другие инструменты
Существуют и другие инструменты, обеспечивающие аналогичную функциональность:
-
pv
(Pipe Viewer): Этот инструмент позволяет вам видеть прогресс передачи данных и может использовать временные файлы для хранения данных, если происходит блокировка. -
tee
с использованием временных файлов: Хотя это решение менее элегантно,tee
может использоваться в комбинации с файловыми операциями для временного хранения данных, но потребуется больше конфигураций и дополнительных скриптов.
Заключение
Ваш взгляд на проблему — это важный шаг к оптимизации потоковой обработки данных в UNIX-подобных системах. Использование инструментов, таких как mbuffer
, значительно облегчает задачи по буферизации данных и позволяет избежать ненужных блокировок, улучшая общую эффективность процессов. Таким образом, вы можете добиться желаемого поведения и обеспечить более плавную работу ваших конвейеров обработки данных.