質問

件名:

繰り返し持続したスケジュールされたタスク(個人的な学習プロジェクトのために)を処理するためにJavaで基本的なジョブスケジューリングを実装しようとしています。 Quartz / Obsidian / Cron4J / etcなどの(使用できる)ライブラリを使用したくない(使用できません)。

目的:

  • ジョブは永続的である必要があります(サーバーのシャットダウンを処理するため)
  • ジョブ実行時間は最大2-5 mNにかかることがあります。
  • 大量のジョブを管理する
  • マルチスレッド
  • ライトと速い;)

私のすべてのジョブはMySQLデータベースにあります。

JOB_TABLE (id, name, nextExecution,lastExecution, status(IDLE,PENDING,RUNNING))
.

ステップバイステップ:

  1. JOB_TABLEの "“nextExecution > now” AND “status = IDLE“"から各ジョブを取得します。このステップは、10mNごとに単一のスレッドによって実行されます。

  2. 各ジョブの最初のジョブには、ThreadPoolExecutorに新しいスレッドを入れてから、ジョブステータスを「PENDING」の「JOB_TABLE」に更新します。

  3. ジョブスレッドの実行中は、ジョブ状況を「RUNNING」に更新します。

  4. ジョブが終了したら、現在時刻にlastExecutionを更新し、新しいnextExecution時間を設定し、ジョブのステータスを "IDLE"に変更します。

  5. サーバが起動しているときは、Pending / RunningジョブをThreadPoolExecutorに入れます。

    質問/観察:

    • ステップ2:ThreadPoolExecutorは大量のスレッド(~20000)を処理しますか?
    • MySQLの代わりにNoSQLソリューションを使用する必要がありますか?
    • そのようなユースケースに対処する最善の解決策はありますか?

    これはドラフトです、後ろのコードはありません。私は提案、コメント、批判に開いています!

役に立ちましたか?

解決

私は実際のプロジェクトであなたの仕事と似ていますが、.netです。これが私があなたの質問に関して思い出すことができるものです:

ステップ2:ThreadPoolExecutorは大量のスレッド(~20000)を処理しますか?

プロジェクトがWebアプリケーションであるため、.NETの組み込みスレッドプールは最悪のアプローチであることを発見しました。理由:Webアプリケーションは、内蔵のスレッドプール(実行中のすべての用途で共有されているため)に依存し、スレッドの効果的なリサイクルを維持しながら、別々のスレッドで各要求を実行します。私たちの内部処理のために同じスレッドプールを使用することはそれを使い果たし、ユーザー要求のための空きスレッドを残したり、彼らのパフォーマンスを台無しにしたりしました。

あなたがかなり多くの仕事を走っているように思われるように(20kは単一のマシンにとってはたくさん)、あなたは間違いなくカスタムスレッドプールを探すべきです。あなた自身のことを書く必要はありませんが、私は準備ができている解決策があり、あなたの研究プロジェクトが必要なものをはるかに超えて* を見る(私が正しく理解している場合は学校や大学プロジェクトをしている場合) )

MySQLの代わりにNoSQLソリューションを使用する必要がありますか?

は依存します。あなたは明らかにジョブの状態を同時に更新する必要があるので、複数のスレッドから1つのテーブルに同時にアクセスすることができます。データベースはあなたが正しくしたと仮定して、それにかなりよく拡張することができます。これが私がこの権利を告げるものです:

  • 各ジョブがデータベース内の独自のサブセットのみに影響を与えるようにコードを設計する(これには他のテーブルが含まれます)。そうすることができると、データベースレベル(トランザクションのシリアライゼーションレベルの形式で)明示的なロックは不要です。汚れやファントムの読み取りを許可できるリベラルなシリアル化レベルを強制することもできます - それはより速く実行されます。しかし、 は、同じ行を介してジョブを回避しないことを慎重に保証する必要があります。これは実生活プロジェクトで達成するのが難しいので、おそらくDBロックで代替アプローチを探すべきです。

  • 適切なトランザクションシリアライゼーションモードを使用します。トランザクションシリアライゼーションモードは、データベースレベルのロック動作を定義します。あなたはテーブル全体をロックするように設定し、あなたが影響を与える行だけ、またはまったく何もしません。どの誤用もアプリケーションまたはDBサーバ全体のデータの一貫性、整合性、および安定性に影響を与える可能性があるため、賢く使用してください。

  • 私はNOSQLデータベースに慣れていないので、並行性機能についての調査を行い、それらをあなたのシナリオにマッピングすることができます。あなたは本当に適切な解決策で終わることができましたが、あなたはあなたのニーズに応じてチェックする必要があります。あなたの説明から、同じ種類のオブジェクトに対する同時データ操作をサポートする必要があります(テーブルのアナログとは何ですか)。

そのようなユースケースに対処する最善の解決策は?

はい、いいえ。

  • はい、開発者が現実の世界に直面しています。私は自分の経験が3回以上持ち、私よりもマルチスレッドタスクをすることには、それを嫌っていた、私は同僚と協力しました。あなたがこの地域があなたにとって面白いと感じているならば、あなたがそれを弾いて、あなたがしなければならない限り学び、改善する。

  • No 、実際のプロジェクトに取り組んでいる場合は、信頼できるものが必要です。あなたが非常に多くの質問をしているならば、あなたは明らかに成熟する時間を必要とし、そのような仕事のための安定した解決策を生み出すことができるでしょう。マルチスレッドは多くの理由で難しいトピックです:

    • デバッグ
    • が難しい
    • それは多くの障害点を紹介し、あなたはそれらすべてを認識する必要があります
    • あなたが一般的に受け入れられた規則に固執しない限り、それは他の開発者があなたのコードを助けたり扱うための苦痛かもしれません。
    • エラー処理は難しい
    • 動作は予測不可能/不定です。

    実際のプロジェクトのための優先アプローチである、高いレベルの成熟度と信頼性を持つ既存の解決策があります。欠点は、あなたがそれらを学び、彼らがあなたのニーズのためのカスタマイズ可能なものを調べなければならないということです。

とにかく、あなたがそれをあなたのやり方をする必要があるならば、そしてあなたの達成を実際のプロジェクトに携帯するならば、あなた自身のプロジェクトにあなたの達成を迎えます。スケジュールされたジョブを設定するロジックから独自の特定の実装を分離するために、abstraction、プログラミングをインタフェース、およびその他の慣行を使用します。そのようにして、これが問題になると既存のソリューションにAPIを適応させることができます。


と最後、ではなく、、私はあなたの側にエラー処理の予測を見ませんでした。仕事が失敗した場合に何をすべきかについて考える。少なくともそのような場合に持続するような「失敗」ステータスまたは何かを追加してください。 Iのときにエラー処理は難しいです

Tはスレッドにやってくるので、あなたの研究と慣行を徹底的にしてください。

頑張って

他のヒント

ThreadPoolExecutor #setmaximumpoolSize(int)で最大プールサイズを宣言できます。 Integer.MAXは、20000より大きい20000が技術的にはいです。

他の問題は、あなたのマシンのwoldが走るために多くのスレッドをサポートしていることです。各トレッドがスタックに割り当てられるように十分なRAMを提供しています。

THEEに問題ないはずです。問題。

DOCから:

コアと最大プールサイズ

ThreadpoolExecutorが自動的に表示されます 境界セットに従ってプールサイズを調整します(getpoolsize()を参照) CorePoolSize(getCorePoolSize())とMaxImumpoolSizeを参照) getMaxImumpOolSize())。新しいタスクがメソッドに送信されたとき 実行(java.lang.runnable)を実行し、CorePoolSizeスレッドよりも少ない 実行されている場合は、他の場合でもリクエストを処理するために新しいスレッドが作成されます。 ワーカースレッドはアイドル状態です。 CorePoolSize以上のものがあれば MaxImumpoolSizeスレッドが実行されるより、新しいスレッドが作成されます キューがいっぱいの場合にのみ。 CorePoolSizeとMaxImumpoolSizeを設定することによって 同じもので、固定サイズのスレッドプールを作成します。設定することにより MaxImumpoolSizeのような基本的に無制限の値へ integer.max_value、プールに任意の収容できます 同時タスクの数最も一般的には、コアと最大プール サイズは建設時にのみ設定されていますが、それらも変更される可能性があります SetCorePoolSize(int)とsetMaxImumpOolSize(int)を使用して動的に。

href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/threadpoolexecutor.html#setmaximumpoolsize(Int )" REL="nofollowNoreferrer">詳細< / a>

DBについて。 DB構造に依存しないソリューションを作成します。それからあなたは2つの団体を設定してそれを測定することができます。あなたが知っている技術から始めます。しかし、他の解決策に開かれています。開始時に、Relations DBはパフォーマンスに続きます。そしてあなたがそれを正しく混ぜるならば、それは後で問題にならないでください。 NOSQLは本当に大きなデータを処理するために使用されます。しかし、あなたに最適なものは、両方を作成して実行する方法を実行することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top