2016-11-29 8 views
1

私はStormプロジェクトを持ち、トポロジクラスは主な方法であるSpout1 - > Bolt1、Spout2 - > Bolt2を持っています。静的変数 - > List of Stringsを持つ別の最終的なutilクラスがあります。今Bolt1はこの静的リストを使用し、Bolt2がリストにStringを追加するようにコンテンツを出力します。 Spout1とSpout2の両方が、それぞれ1000msと500msの間隔でそれぞれのボルトにメッセージを発信しています。実際のクラスタ環境でStorm Bolts/SpoutでGlobal Static変数を使用することは可能ですか?

従業員数を4、つまりConfig.setNumWorkers(4)に設定しました。

並列ヒント:SPOUT1 - 1、Bolt1 - 100、SPOUT2 - 1、Bolt2 - 100

このコードの設定は、私のウィンドウのマシンにLocalClusterモードで動作しています。

しかし、これがlinuxの実際のクラスタ環境で動作するかどうかはわかりませんが、Supervisor deamonをケータリングする複数のサーバがあります。実際のクラスター環境では、異なるJVMプロセスを持つ異なるマシンでワーカーが動作すると仮定します。 ボルトがローカル静的変数、つまりローカルクラスターで実行できるストリングリストにアクセスできるようになりますか?以下は

参照するためのいくつかのコードを行く:成功し、実行に

public static void main(String[] args) { 

    System.out.println("Starting Topology...."); 
    TopologyBuilder builder = new TopologyBuilder(); 

    builder.setSpout("spout12", new TestSpout2(), 1); 
    builder.setBolt("bolt12", new TestBolt2(), 100).shuffleGrouping("spout12", "spout12Stream"); 
    builder.setSpout("spout11", new TestSpout1(), 1); 
    builder.setBolt("bolt11", new TestBolt1(), 100).shuffleGrouping("spout11", "spout11Stream"); 

    Config conf = new Config(); 
    conf.setDebug(false); 
    conf.setNumWorkers(4); 
    LocalCluster cluster = new LocalCluster(); 

    cluster.submitTopology("TestTopology3", conf, builder.createTopology()); 

} 


Spout1 : 
public void nextTuple() { 
    int a = (int) (((Math.random() * 10)+1)*((Math.random() * 10)+1)); 
    String str = String.valueOf(a); 
    Utils.sleep(1000); 
    collector.emit("spout11Stream", new Values(str), str); 
} 


Bolt1 : 
public void execute(Tuple tuple) { 
    System.out.println("########## In execute of TestBolt11....\t Value 0 : " + tuple.getString(0) + "\t\t List : " 
      + CommonUtils.list); 
    _collector.ack(tuple); 
} 


Spout2 : 
public void nextTuple() { 
    int a = (int) (((Math.random() * 10)+1)*((Math.random() * 10)+1)); 
    String str = String.valueOf(a); 
    Utils.sleep(500); 
    collector.emit("spout12Stream", new Values(str), str); 
} 


Bolt2 : 
public void execute(Tuple tuple) { 
    System.out.println("!!!!!!!!!!!!! In execute of TestBolt12....\t Value 0 : " + tuple.getString(0)); 
    CommonUtils.list.add(tuple.getString(0)+"gb"); 
    _collector.ack(tuple); 
} 


CommonUtilis class : 
public final class CommonUtils { 
public static List<String> list = new ArrayList<String>(); 
} 

SYSOUTを:

!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 31 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 9 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 68 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 24 
########## In execute of TestBolt11....  Value 0 : 39  List : [31gb, 9gb, 68gb, 24gb] 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 60 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 30 
########## In execute of TestBolt11....  Value 0 : 26  List : [31gb, 9gb, 68gb, 24gb, 60gb, 30gb] 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 9 
!!!!!!!!!!!!! In execute of TestBolt12.... Value 0 : 15 
########## In execute of TestBolt11....  Value 0 : 11  List : [31gb, 9gb, 68gb, 24gb, 60gb, 30gb, 9gb, 15gb] 

答えて

0

短い答えはノーである、静的変数のアクセスがJVMによってスコープされ、あなたは、いくつかありますJVMはあなたが指摘しているとおりです。あなたは静的変数にアクセスする1の並列化のヒントとボルトを持つことができ

  1. はカントー、いくつかの回避策があります。 1つのボルトしかないので、アクセスは1つのJVMで行われますが、再度、そのボルトにインスタンス変数を使用することもできます。

  2. (1)のバリエーションは、嵐でスケジューラーの実装を使用して、ボルトの複数のインスタンスを持つことですが、すべて同じワーカーに割り当てられます。このアプローチは私が試したことではありませんが、とにかくそこに投げ捨てると思っていました。
  3. クラスタ全体に広がるデータの読み取り/書き込みストアとして、リレーショナルデータベースまたはNoSQLデータベースを使用できます。
  4. リストを動物園に格納できます。私はあなたのボルトの実装をより簡単にするために、シングルトンクラスでの動物園のアクセスをラップします。
+0

ありがとうございました。私の実際の問題は、私は100のボルトを持っている、それぞれの文字列の行を読んで、正規表現のリストに基づいて私たちの特定のテキストを選んでいる今、この正規表現のリストは、別のWebアプリケーションから変更し続けます。ここで静的変数はオプションではないので、私の100ボルトすべてに独自のキャッシュが必要です。しかし、どうすればこれらの100個のボルトのキャッシュを同時に失敗なく更新できますか? 1.すべてのグループ化はオプションですが、同じキャッシュを100個のボルトで保持したくないので、別の方法で簡単に使用できます。 – Gaurav

+0

DBのやりとりにより、ボルトの動作が遅くなります。したがって私は毎回正規表現のリストを取得するためにDBを使用することはできません。 – Gaurav

関連する問題