Storm經驗總結

其實我是真性情發表於2015-07-24

1. Storm啟動命令

我啟動Strom命令以後就卡在那了,Ctrl+C或者關閉SSH都會導致服務關閉。

正確的啟動命令是

storm ui &

然後敲

exit

退出以後,再關閉SSH服務就不會關閉了。


2.Storm釋出命令

我將我本地執行正常的StromTopology工程,打成jar包

放到了storm的安裝目錄下的lib下

我的目錄是

/usr/local/apache-storm-0.9.3/lib

然後把a.jar包複製到這個目錄下,然後敲命令

storm jar a.jar test.SimpleTopology lwb_1

其中,黑色的'storm jar'是strom命令;紅色的是我工程的jar包;藍色的是我jar包裡的主函式;最後lwb_1是我給服務起的名字。


3.Storm載入問題

我用一個工程打了2個jar包名字不一樣,其中a.jar裡邊用的主函式是A;b.jar主函式是B

當然,A與B在a.jar和b.jar都有。

然後在A類和B類裡,我都呼叫了C類。

這個時候,我放到strom上,先啟動a.jar,然後卡住了。不知道為什麼,我這個strom每次釋出服務以後,都得卡半天,大概一分鐘左右的時間,才能開始執行。

然後我又啟動b.jar

如果我只啟動a.jar,那麼卡一分鐘左右會執行。

但是當我啟動a.jar以後馬上改成啟動b.jar

就會出現b.jar馬上就執行了,但是a.jar就再也不執行了。

我目前的猜想是A與B都呼叫了C類。而B先載入了C類。所以A執行等待B釋放C。所以A就卡住不懂了這只是我的猜想。

所以我要說的是,如果在strom上,跑2個任務,最好類別重複。

4.Storm裡Executor跟Task的關係

之前一直沒怎麼想網上跟資料上說的他們2的關係是什麼意思。直到我寫了下邊的程式碼。

  topologyBuilder.setBolt("simple-bolt", new SimpleBolt(), 3).setNumTasks(2).shuffleGrouping("simple-spout");

這裡可以看見我在程式碼裡顯示的設定了Executor為3,Task的數量為2.

然後執行的時候我發現storm UI監控裡Executor跟Task的數量都是2個。但是我程式裡明明設定的是3個。

這個時候再回去想書上寫的東西,我就明白了,Task是在Executor執行緒裡邊跑的,而且一個

Executor必須要有一個Task,這個時候,因為我的程式只設定了2個Task,所以有一個Executor根本沒有Task可以跑,所以這個不是沒有了,就是沒跑。

所以在監控頁看見的Executor跟Task的數量才都是2個。


5.storm多執行緒導致資料不對的問題。

這幾天一直在做試驗,我是從在strom的spout裡從kafka裡取資料出來,然後在bolt裡插入到Hbase裡。有的時候用多執行緒以後就會出現資料對不上的問題,找了半天。

最後發現是插入的時候,記錄rowkey我用的是bolt裡的一個Long型的靜態變數,導致出現資料條數不對的情況,我把資料的rowkey保證唯一以後,問題不再出現。


5.storm的Bolt與Bolt之間可以直接傳遞物件因為Values就是繼承了一下ArrayList,但是這個物件要傳遞就必須序列化,否則會報錯。

public void execute(Tuple input) {
		try {
			A a = new A();
			String mesg = input.getString(0);
			Integer aaa = 1;
			if (mesg != null) {
				 collector.emit(new Values( mesg+"mesg is processed!",mesg,a));
//				 System.out.println("Bolt"+this.hashCode()+":"+mesg);
			}
		} catch (Exception e) {
			e.printStackTrace(); // To change body of catch statement use File |
			collector.fail(input);						// Settings | File Templates.
		}
		collector.ack(input);
	}

在下個bolt裡,直接取就可以,或者直接getValue也行,這裡的"obj"是在declareOutputFields裡宣告的

A a = (A)input.getValueByField("obj");

A.java

public class A implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -6812487879564685130L;

	public void aaa(String a) {
		HashMap<String, String> map = new HashMap<String, String>();
		System.out.println(a+map);
	}

}