1

私は、ネットワークを介して約1000台の測定デバイスからデータを収集し、そのデータをデータベースに保持するスタンドアロンのJavaアプリケーションを開発しています。デバイスの出力やネットワーク速度が遅いため、データ収集にはデバイスごとに数分かかる場合があります。データ収集は特定の時間枠で行われる必要があるため、並行して作業する必要があります。

私のアプローチは、測定デバイスごとに1つのスレッドを作成し、データをキューに入れ、キューのもう一方の端に1つ以上の他のスレッドを変換して、データを永続化することです。

これは実行可能なアプローチですか?最新のマシンは、その数のスレッドとネットワーク接続を処理できますか?これはどの程度スケーラブルですか。どの時点で複数のマシンで作業する必要がありますか?

また、推奨する並行クラスに関するポインタを教えていただければ幸いです(つまり、どのような種類のキュー、ThreadPoolExecutorなど-私はまだjava.util.concurrentを使用していませんが、本はメールにあります)。

より良いアプローチはありますか?

アップデート:

これまでの回答に感謝します。ここにあなたの何人かによって要求されたより多くの情報があります。

デバイスから受信するデータは、1kb未満のファイルの形式です。通常ははるかに少ないですが、1回の転送で25.000ファイルのようなものを取得する可能性があります。

データ変換はCPUを集中的に使用するものではなく、基本的にファイルを解析してJavaデータ型(ファイルにはunsigned charやunixタイムスタンプなどのcデータ型が含まれます)に変換し、さらにCRC計算を行います。JPAを使用してデータベースに永続化する1つのファイルのコンテンツを含むオブジェクトを作成します(この場合はプレーンJDBCも使用できると思います)。測定ファイルにはデバイスのs/nとタイムスタンプが含まれているため、順序はありません。

後で、特定の基準が満たされたときに何らかのアラートを追加する必要がありますが、これもCPUを集中的に使用するべきではありません。

これまでの回答から、ネットワーク接続を収集し、スレッドの数は問題にならないはずです。

私が疑問に思っているのは、キューを使ったアプローチだけです。別の方法は、データ収集スレッドがDAOメソッドを呼び出してファイルを永続化できるようにすることです。とにかくDAOをスレッドセーフにする必要があると思いますが、時間の大部分がネットワークデータの転送に費やされるため、いくつかのスレッドでも同じように機能すると思います。

また、非同期I/Oとそれを提供するいくつかのフレームワークについても調べます。

もう一度ありがとう、私は少し後で答えを選びます、多分私はもう少し入力を得るでしょう:)

4

3 に答える 3

1

最新のOSとハードウェアの場合、1000以上の変更スレッドとネットワーク接続の処理は問題になりません。本当の問題は、収集するデータの量と、変換がどれほど複雑かということです。これにより、1台のマシンで処理できる量が決まる可能性があります。

于 2012-05-31T09:50:11.343 に答える
1

デフォルト設定では、64 ビット Linux、Oracle jdk で実行している場合、スレッドのスタックに約 1Gb のメモリを使用することになります (デフォルトのスレッドスタックサイズは、このようなプラットフォームでは 1Mb です)。OpenJDKでも同じだと思います。os によって割り当てられたバッファは数えません。. .

これが要件に対して多すぎる場合は、http://netty.ioを確認してください。このフレームワークは内部で Java nio を使用します (bio を使用するように構成できます)。この方法では、実際の io を実行する (特定の tcp 接続に対して読み取り/書き込み操作を実行する) ために少数のスレッドが必要になります。次に、ビジネス ロジック (データベースの更新、いくつかの測定値の計算) を別のスレッドプールにオフロードする必要があります。Netty には、これに対するサポートも含まれています。

接続ごとに (測定デバイスごとに?) 1 つのスレッドを使用する場合、実際のビジネス作業を実行する別のスレッドの束をもう 1 つ用意してもおそらくメリットはありません。デバイスが遅くなる可能性がある、および/またはネットワークが遅くなる可能性があると言ったので、デバイスごとに1つのスレッドを想定しています。複数のスレッドを使用している場合、両方のボトルネック (ネットワークとデバイス) は解消されません (反対のことが予想されます)。

一般的な同時実行クラス: java.util.concurrent.* はい、どちらも賛成です

于 2012-05-31T10:15:52.667 に答える
0

IMO、デバイスからデータを収集するために非同期 IO を検討する必要があります。ソケットから何かを読み取ったら、これをキューにポストし (同時またはそれ以外)、このキューからアイテムを読み取るスレッドのプールを用意します。

唯一の複雑さは、デバイスの自然な順序でデータを維持することです。おそらく、デバイスごとにキューを作成し、スレッドプールが接続されているキューにある種のトークンを投稿して、どのデバイスが処理の準備ができているかを示します。次に、スレッドはデバイスのキューを処理し、必要な作業を行います。さらにデータが必要な場合は、デバイス キューから消費する必要はありません。すべてのデータが到着するまで、スレッドをそのままにしておくことができます。

于 2012-05-31T10:15:40.647 に答える