1

私は Apache ストームを初めて使用します。1 つのスパウトと 2 つのボルトを含むコードを書きました。この 3 つの部分を 1 つのワーカーで実行すると、コードは正しく出力を生成しますが、1 つのワーカーが実行する 3 つのワーカーでコードを実行すると、スパウト、別のランボルト 1、最後のランボルト 2 の場合、出力は生成されません。特定の状況: 1 つのワーカーにボルト 1 と 2 を配置すると、出力が生成されました!

エミットは正常に機能し、エミット変数に問題はないと言わざるを得ません。

詳細: ボルト 1 でハッシュマップ構造にツリーを作成しました。ボルト 2 でこのツリーをマイニングしたいと思います。ボルト 1 でツリーに挿入されるオブジェクトの ID は "MyTreeNode@e70014d5" のようになり、このタプルを受け取ったとき (ハッシュマップ) ボルト 2 では、ID が「MyTreeNode@z5542r12」のようなものに変更されました。

主な問題は何ですか?

問題はオブジェクト ID の変更によるものですか? はいの場合、どうすれば解決できるか教えてください。

4

1 に答える 1

1

トポロジーの例を見てみましょう。

トポロジがスパウト -> ボルト 1 になり、スパウトから MyObject インスタンスを放出しているとします。

1 つのワーカーで実行するようにトポロジを設定したとします。

タプル (MyObject@1234 など) がスパウトから発行されると、Storm はタプルを別のワーカーに渡す必要があるかどうかを確認します。そうでない場合は、オブジェクト参照を単にbolt1に渡します。これは、ワーカーが 1 つしかない場合に表示されるものです。MyObject@1234 をスパウトからボルトに転送する必要がある場合、Storm はボルトに MyObject@1234 参照を渡すだけです。

ここで、2 つのワーカーを使用するようにトポロジーに指示し、Storm がスパウトをワーカー 1 に、ボルトをワーカー 2 に配置することを決定したとします。各ワーカーは個別の JVM プロセスであることを思い出してください。したがって、オブジェクト参照をワーカー 1 からワーカー 2 に渡します。動作しません。

タプルがスパウトから発行されると、Storm はそれが別のワーカーに送信されることを認識し、構成に応じて Kryo または Java シリアル化を使用してシリアル化します。これは、MyObject@1234 がシリアライズされることを意味します。Storm はシリアル化されたフォームをワーカー 2 に渡し、ワーカー 2 はそれを逆シリアル化します。デシリアライズされると、非常に合理的な新しいメモリ アドレスが割り当てられます (例: MyObject@6789)。

ボルトが同じ JVM で実行されていないことを想定してボルトを設計する場合、これは問題ではありません。これは絶対に行う必要があります。たとえば、ワーカー 1 からワーカー 2 に MyObject を転送する場合は、それをシリアライズ可能にするか、Kryo に登録します ( https://storm.apache.org/releases/2.0.0-で方法を参照してください)。 SNAPSHOT/Serialization.html )。これを行う必要があるのは、Storm がトポロジーを壊さずにスパウトとボルトを別々の JVM に配置できるようにするためです。

トポロジをテストするときは、https://storm.apache.org/releases/1.2.2/javadocs/org/apache/storm/Config.html#TOPOLOGY_TESTING_ALWAYS_TRY_SERIALIZEを有効にする必要があります。これにより、タプルがワーカー間で転送されていない場合でも、Storm は常にタプルをシリアル化します。これにより、シリアライゼーションの問題を本番環境に移行する前に把握できます。

余談ですが、常に Java シリアライゼーションよりも Kryo シリアライゼーションを優先する必要があります。Kryo のシリアル化ははるかに高速です。

于 2019-01-14T21:25:59.157 に答える