1. ホーム
  2. node.js

[解決済み] Node.jsで巨大なログファイルを解析する - 1行ずつ読む

2022-05-15 15:09:46

質問

私はJavascript/Node.jsで大規模な(5〜10Gb)ログファイルのいくつかのパースを行う必要があります(私はCubeを使用しています)。

ログラインは次のようなものです。

10:00:43.343423 I'm a friendly log message. There are 5 cats, and 7 dogs. We are in state "SUCCESS".

各行を読み込んで、いくつかのパース(たとえば 5 , 7SUCCESS ) を作成し、このデータを Cube に取り込みます ( https://github.com/square/cube ) に送信します。

まず最初に、Nodeでファイルを一行ずつ読み込む標準的な方法は何でしょうか?

これはネット上ではかなり一般的な質問のようです。

多くの回答は、サードパーティモジュールの束を指しているようです。

しかし、これはかなり基本的なタスクのように思えます。確かに、stdlib の中にテキストファイルを一行ずつ読み込む簡単な方法があるのでしょうか?

次に、私は各行を処理する必要があります(たとえば、タイムスタンプをDateオブジェクトに変換し、有用なフィールドを抽出します)。

これを行うための最良の方法は何でしょうか、スループットを最大化するために?各行の読み取りまたは Cube への送信のいずれにおいてもブロックされない何らかの方法はありますか?

3 番目に、文字列分割と、JS に相当する contains (IndexOf != -1?) を使用すると、正規表現よりもはるかに高速になると推測していますが、いかがでしょうか。Node.js で大量のテキスト データを解析した経験のある方はいらっしゃいますか?

乾杯。 ビクター

どのように解決するのですか?

私は、ストリームを使用して、非常に大きなファイル (gbs) を行ごとに解析するソリューションを探しました。すべてのサード パーティ製ライブラリおよびサンプルは、ファイルを行ごとに (1, 2, 3, 4 のように) 処理しないか、ファイル全体をメモリに読み込むため、私のニーズに合いませんでした。

次のソリューションは、ストリームとパイプを使用して、非常に大きなファイルを 1 行ずつ解析することができます。テストでは、17.000.000 レコードの 2.1GB ファイルを使用しました。ラムの使用量は 60 mb を超えませんでした。

まず イベントストリーム パッケージをインストールします。

npm install event-stream

では

var fs = require('fs')
    , es = require('event-stream');

var lineNr = 0;

var s = fs.createReadStream('very-large-file.csv')
    .pipe(es.split())
    .pipe(es.mapSync(function(line){

        // pause the readstream
        s.pause();

        lineNr += 1;

        // process line here and call s.resume() when rdy
        // function below was for logging memory usage
        logMemoryUsage(lineNr);

        // resume the readstream, possibly from a callback
        s.resume();
    })
    .on('error', function(err){
        console.log('Error while reading file.', err);
    })
    .on('end', function(){
        console.log('Read entire file.')
    })
);

<イグ

どうなったか教えてください!