パイプラインで無制限の量のデータをバッファリングするユーティリティ?


13

パイプラインに固執して読み取りと書き込みの速度を分離できるユーティリティはありますか?

$ producer | buf | consumer

基本的に、buf可能な限り高速に入力を読み取り、メモリに保存して、可能な限り高速で実行しconsumerながら甘い時間を過ごすことができるユーティリティが必要ですproducer


私もそのように見たいです
アンティハパラ

stdbufツールがあるように思われるsizeパラメータ。それが動作するかどうかはわかりません。
CMCDragonkai

回答:


13

pv(パイプビューア)ユーティリティは、(でこれを行うことができ-Bますが、経過報告与え含め、より多くのオプション)と。


これを無制限のデータ量で行う方法はありますか?私の知る限り、-Bで数値を指定する必要があります。プロデューサーがコンシューマーよりもはるかに先に進んだ場合、プロデューサーは再びスローダウンします。複数のコンシューマーが存在する状況にある場合(producer | tee >(pv -cB $SIZE | consumer1) | pv -cB $SIZE2 | consumer2)、これにより再びスローダウンが発生する可能性があります。
ダニエルH

私はpv何百回も使用しましたが、これを知りませんでした。とても素晴らしい、ありがとう!
Rucent88

pv -B 4096 -c -N in /dev/zero | pv -q -B 1000000000 | pv -B 4096 -c -N out -L 100k > /dev/null- pv両端の両方がスムーズであると期待しています(ただし、どちらも1GB先です)。それはとは異なり、このように動作しませんmbuffer
Viに。

9

あなたが使用することができますdd

producer | dd obs=64K | consumer

すべてのUNIXで利用可能です。


標準ユーティリティpvを使用する場合は+1を使用しますが、おそらく使用するほうがよいでしょう(進行状況を表示します)。
トーター

2
それは実際に読み書き速度を切り離しますか?dd一度に1つのブロックしか保存しないように見えるため、ブロックサイズを生成するのにかかる時間だけすべてを遅延させます。私が間違っている場合は修正してください。また、このバッファリングを無制限のサイズに拡張したり、ブロックサイズに入力したものだけを拡張したりできますか?
ダニエルH

@DanielH-今はそうです。
mikeserv

7

mbufferを見てください。メモリまたはメモリマップファイル(-t/ -T)にバッファリングできます。


他の人に尋ねたように、必要なだけバッファリングするように指示する方法はありますか、または最大サイズを持っていますか?これらのプログラムのほとんどに最大サイズがあり、たとえば、より小さいバッファーのリンクリスト(または他の任意のサイズのキュー実装)を使用しない概念的な理由はありますか?
ダニエルH

おそらくメモリ不足エラーを防ぐためです。必要な場合は、おそらくオプションを使用して非常に大きなバッファー(4GB程度)を設定できます(試してみてください)。
デビッドバラジック

1

これは基本的に否定的な答えです。これは、どちらもそれを表示されないdd、またmbuffer、またしてもpv動作しますプロデューサーによって生成されたデータの割合が多くを変えることができれば、特に、すべてのケースです。以下にいくつかのテストケースを示します。コマンドを入力した後、約10秒間待ってから入力します>(データの最後に移動する、つまり入力の終わりを待ちます)。

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | dd bs=64K | less

ここでは、を入力した後>、5秒間待機する必要がありsleep 5ます。つまり、プロデューサー(zshスクリプト)はの前にブロックされています。bsサイズをたとえば32Mに増やしても動作は変わりませんが、32MBのバッファーは十分に大きくなります。これはdd、入力を続行するのではなく、出力をブロックするためだと思われます。oflag=nonblockこれはデータを破棄するため、使用は解決策ではありません。

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | mbuffer -q | less

mbuffer、問題は、最初の行(foo0)がすぐに表示されないということです。入力時に行バッファリングを有効にするオプションはないようです。

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | pv -q -B 32m | less

ではpv、動作がに似ていますdd。さらに悪いことに、端末からless入力を受け取ることができない場合があるため、端末に対して間違った動作をすると思われます。たとえば、で終了することはできませんq


0

非標準の移動:ソケットバッファーを使用します。

例:

# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
        i:  468MB 0:00:16 [ 129kB/s] [  <=>                        ]
        o: 1.56MB 0:00:16 [ 101kB/s] [       <=>                   ]

このために、buffered_pipelinemapopentounixsocketの 2つの追加ツールを実装しました

$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
        1: 13.4MB 0:00:40 [ 103kB/s] [         <=>      ]
        2: 3.91MB 0:00:40 [ 100kB/s] [         <=>      ]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.