私の仕事では、次の問題の解決策を開発して実装することでした。
30M レコードのデータセットが特定のデータセット フィールドから (キー、値) タプルを抽出し、それらをキーと値でグループ化し、各キーの同じ値の数を格納します。各キーの上位 5000 個の最も頻度の高い値をデータベースに書き込みます。データセットの各行には、シリアル化された XML の形式で最大 100 個の (キー、値) タプルが含まれます。
私はこのような解決策を思いつきました( Spring-Batchを使用):
バッチ ジョブの手順:
ステップ 1.データセットの行を繰り返し処理し、(キー、値) タプルを抽出します。一定数のタプルを取得すると、それらをディスクにダンプします。各タプルは名前パターン「/chunk-」のファイルに移動するため、指定されたキーのすべての値が 1 つのディレクトリに格納されます。1 つのファイル内で値がソートされて格納されます。
ステップ 2.すべての '' ディレクトリを繰り返し処理し、それらのチャンク ファイルを同じ値をグループ化した 1 つのファイルにマージします。値はソートされて保存されるため、O(n * log k) の複雑さでそれらをマージするのは簡単です。ここで、「n」はチャンク ファイル内の値の数、「k」はチャンクの初期数です。
ステップ 3.マージされた各ファイル (つまり、各キー) について、PriorityQueueを使用してその値を順番に読み取り、すべての値をメモリにロードすることなく、上位 5000 の値を維持します。キューの内容をデータベースに書き込みます。
このタスクに約 1 週間を費やしました。これは主に、Spring-Batch を使用したことがないことと、マルチスレッド部分の正確な実装を必要とするスケーラビリティーを重視しようとしたことによるものです。
問題は、私のマネージャーが、このタスクはあまりにも簡単すぎて、それほど多くの時間を費やすことができないと考えていることです。
そして質問は、より効率的なソリューションを知っていますか、それとも実装が簡単な効率の悪いソリューションを知っていますか? そして、私のソリューションを実装するのにどれくらいの時間が必要ですか?
MapReduce のようなフレームワークがあることは知っていますが、アプリケーションは 3 コア、Java ヒープに 1GB の単純な PC で実行することになっているため、使用できません。
前もって感謝します!
UPD: 質問を明確に述べていなかったと思います。別の言い方で質問させてください:
問題があり、プロジェクト マネージャーまたは少なくともタスクのレビュー担当者である場合、私の解決策を受け入れますか? また、このタスクにどのくらいの時間を割きますか?