storm topology優化之lib庫分離

jopen 10年前發布 | 6K 次閱讀 Java開發

最近在基于storm做實時分析統計工作,每次將topology打包上傳到服務器上,都是一個艱難的事情,原因有里兩個:

1,因為一個topology,如果引用了第三方包,體積就會變大,上傳時間隨著包體成正比例。

2,加大Nimbus、Supervisor、Zookeeper的網絡壓力。


先簡單描述storm運行一個topology的流程:

1,提交topology.jar后,jar包上傳到Nimbus的${storm.local.dir}/inbox目錄中,之后把該jar包序列化到stormdist目錄中。

2,Nimbus根據topology設定的spout、bolt數分配worker,nimbus會根據spout、bolt的數量盡量平均分配到每個worker

3,nimbus將任務信息(包括代碼)提交到zookeeper集群上,保存當前topology與所有worker進程的心跳信息(workerbeats節點);同時將topology的任務分配信息、代碼存儲目錄、任務之間的關聯關系保存到assignments節點下。

4,supervisor不斷輪詢zookeeper的assignments節點上,是否有自己的任務。當輪詢到有自己的任務,將會任務信息(包括代碼)。

5,topology開始執行之后,spout不斷發stream流,bolt不斷接受stream流。如果執行過程中,某個worker多次執行失敗,supervisor會發揮給nimbus重新調度分配。


上述5步中,1、3、4都涉及到代碼的網絡傳輸。假如topology包體很大的話,并且分配的worker比較多,那傳輸包體的瞬時帶寬就很高。


利用maven打包優化

mvn 打包時,配置classpathPrefix來指定所有依賴JAR文件的前綴,即在運行時,添加一個額外的ClassPath。然后在storm集群,新建剛剛指定的classpathPrefix目錄,將topology所依賴的包都放進去。完成后,當我們打包時,只要將具體的業務代碼上傳就可以。


示例:

在pom文件下添加如下配置:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <addMavenDescriptor>false</addMavenDescriptor>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>YOUR_LIB_PATH</classpathPrefix>
      </manifest>
    </archive>
  </configuration>
</plugin>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <!-- 配置assembly組件 -->
    <descriptors>
      <descriptor>package.xml</descriptor>
    </descriptors>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

將上面的YOUR_LIB_PATH替換成你的目錄。

再在項目下添加package.xml文件(上面的pom.xml中指定的),文件內容如下:

<assembly>
    <id>bin</id>
    <!-- 最終打包成一個用于發布的zip文件 -->
    <formats>
        <format>zip</format>
    </formats>

    <!-- Adds dependencies to zip package under lib directory -->
    <dependencySets>
        <dependencySet>
            <!--
               不使用項目的artifact,第三方jar不要解壓,打包進zip文件的lib目錄
           -->
            <useProjectArtifact>false</useProjectArtifact>
            <outputDirectory>lib</outputDirectory>
            <unpack>false</unpack>
        </dependencySet>
    </dependencySets>

    <fileSets>
        <!-- 把項目自己編譯出來的jar文件,打包進zip文件的根目錄 -->
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory></outputDirectory>
            <includes>
                <include>*.jar</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>


來自: http://my.oschina.net/ericquan8/blog/600446

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!