スレッドで処理資源を制限する

課題説明

今って、大きく課題にアサインしてもらった。現状は、データ数が多すぎるので、そして、データ抽出したあとにそのロジックコードも長すぎる、ざっくりみると、20000行以上である。中で別システム連携であるのみにならず、DBデータの再抽出も多い。

テストの最小単位で3万件のデータをダウンロードに試してましたが、ローカルの開発環境で全然無理です。15分ほどにかかったあと、すぐダンしてしまった。

プロジェクトリーダーは「エラーになる行を見て、解決してください。」と言った

僕にとって日本では技術のことが知らないリーダーが多いです、実際はこんなに簡単に解決ではなく、性能問題は開発の段階に考えられるものと思うですが、仕様不備やスケジュールを合わせるため、開発段階にもややこしかったかもしれない

ほぼ、現状を把握から解決まで二週間を経った、問題は以下になる

  1. loopの中にLoopが多すぎる
  2. 全件数を抽出した、未出力のデータって長期にメモリーを占用する
  3. 全データ処理後一瞬にファイルを出力する、400MBくらい
  4. SQL:where id in(...2000個以上のストリング...)
  5. 本番環境のメモリーは4GBがあるのに、2GBだけ使われてる

実現目標

100000件以上のデータがダウンロードできるように修正


アーキテクチャはこうになる






解決案


一番目の解決案はリストタイプをMapタイプに修正すればOKです。


二番目は全件数を抽出したので、回数による処理件数を制御すると僕は考えてます。リーダーさんは、「処理件数」だけで制御いけないかという質問を頂きました。
1人は「500件」、10人同時にダウンロードすれば並列件数が5000件です。30人なら、15000件。
以上の問題をもって、実験したが、5000件以内は別の機能に性能影響が最も小さい。


三番目の解決案は、一行ずつファイルに出力する、処理後にCSVの該当オブジェクトをNullにして、JVMがメモリー資源を自動的に開放できる


四番目は根拠の問題はMySQLのインデックスに走らなかったです、INの結合句は2000以上であるので。これに対すて、新しくテーブルを作成しました、毎回処理の回数データは「insert into new_table_name(申込ID) select * from old_table_data」テーブルにインサートする、別のSQL分抽出のデータはLeft Joinの結合句を追加していい、そして、プログラムに経由しなく、SQL分の組み立てる時間もなかった。当該回数処理する後、テーブルのデータを抹消する。


五番目は、インフラチームに触れないため、避けるしかない


最後

15 万件のテストデータは一人10分ほどかかるという実績を出てきました。

同時に5人ダウンロードできる。同時の処理件数が「5000件」、もちろん、すべてプロパティファイルに配置できる

全100000件/一回処理1000件=100回数

6人同時にダウンロード場合は、一人は列に並ぶ、スレッドプールが空いたら、スレッド処理を行う。


评论