jstorm學習筆記--初識(一)

什麼是jstorm

基本概念

  1. 元組(tuple)

    jstorm 消息傳遞的基本單位,是一個命名的值列表,元組中的字段可以是任何類型的。支持所有的基本類型、字符串和字節數組,也支持自定義的序列化接口對象。

  2. 流(stream)

    數據之間通過流進行傳遞,是核心抽象。流有元組組成,實質是元組序列。

  3. 龍捲(spout)

    拓撲中流的來源,即數據的來源。

  4. 閃電(bolt)

    流的處理節點,即接受到spout流出的數據並進行處理。

  5. 流分組(Stream grouping)
    spout和bolt、bolt和bolt之間數據如何分發和接受,通過流分組定義。流分組定義了流/元組如何在bolt任務之間分發。
  6. 拓撲(topology)

    各組件的消息流動形成邏輯上的拓撲結構,是jstorm中一個實時應用程序。類似於MapReduce 的作業。拓撲與MapReduce的區別在於,後者的作業始終會完成,而拓撲會永遠運行知道他被kill。

  7. 工作進程(worker)

  8. 任務(task)
  9. 執行器(executor)
  10. 主空節點和工作節點
    集羣有主控節點(MasterNode)和工作節點(Worker Node) ,主控節點只有一個,工作節點有多個。
  11. nimbus進程和supervisor進程
    主控節點運行nimbus進程,類似hadoop的jobTracker,用來在集羣中分發jar,對節點進行任務分配,並檢測主機故障。工作節點運行supervisor進程,監聽主機分配的作業。

==總結:==
jstorm 的各組件關係,可以用一句話來概括:
一個topology 包含多個spout和bolt ,bolt和spout的基本單位是tuple,spout 和bolt、bolt和bolt之間通過stream傳遞數據。數據的傳遞和接受規則通過流分組實現。

如何創建一個簡單的topology

創建一個簡單的topology
  1. 實現spout接口
    數據處理的數據來源,接受數據
  2. 實現bolt接口
    從spout中接受數據進行邏輯處理
  3. 生成topology
    畫出拓撲圖,spout、bolt之間的關係

如下是一個簡單的topology定義

# pom文件中引入jstorm依賴
 <dependency>
            <groupId>com.alibaba.jstorm</groupId>
            <artifactId>jstorm-core</artifactId>
            <version>2.4.0</version>
            <!--本地測試時需要註釋,提交集羣時需要釋放註釋-->
            <scope>provided</scope>
        </dependency>

# 1. 定義spout
public class SimpleSpout implements IRichSpout {

    private static final Logger LOG = LoggerFactory.getLogger(com.hollycrm.hollyvoc.batchexample.SimpleSpout.class);
    private Random rand;
    private int batchSize = 100;
    private SpoutOutputCollector collector;


    @Override
    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
        rand = new Random();
        rand.setSeed(System.currentTimeMillis());
        this.collector = collector;
    }

    @Override
    public void close() {

    }

    @Override
    public void activate() {

    }

    @Override
    public void deactivate() {

    }

    @Override
    public void nextTuple() {
        for (int i = 0; i < batchSize; i++) {
            long value = rand.nextInt(10);
            collector.emit("stream-id",new Values(value));
        }
    }

    @Override
    public void ack(Object msgId) {

    }

    @Override
    public void fail(Object msgId) {

    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declareStream(
                "stream-id",
                new Fields("value")
        );
    }

    @Override
    public Map<String, Object> getComponentConfiguration() {
        return null;
    }
# 2. 定義bolt
public class SimpleBolt implements IBasicBolt {
    public final static String NAME = "simple-bolt";

    private static Logger logger = LoggerFactory.getLogger(SimpleBolt.class);
    @Override
    public void prepare(Map stormConf, TopologyContext context) {

    }

    @Override
    public void execute(Tuple input, BasicOutputCollector collector) {
        if("stream-id".equals(input.getSourceStreamId())) {
            try {
                Long value = input.getLongByField("value");
                // todo 對value 邏輯處理
                logger.info(" 接受到的值是: " + value);
            } catch (Exception e) {

            }
        }
    }

    @Override
    public void cleanup() {

    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {

    }

    @Override
    public Map<String, Object> getComponentConfiguration() {
        return null;
    }

# 3. 構建topology

public class SimpleTopology {
    // 拓撲名稱
    private static String topologyName = "SimpleTopology";

    private static Logger logger = LoggerFactory.getLogger(SimpleTopology.class);


    /**
     * 定義拓撲
     *
     * @param topology 拓撲對象
     * @param conf     配置
     */
    public static void defineTopology(TopologyBuilder topology, Map<String, Object> conf) {

        TopologyBuilder topologyBuilder = new TopologyBuilder();

        int spoutParallel = JStormUtils.parseInt(conf.get("topology.spout.parallel"), 1);

        // 聲明spout
        SpoutDeclarer spoutDeclarer = topologyBuilder.setSpout("simple-spout",
                new SimpleSpout(), spoutParallel);

        int boltParallel = JStormUtils.parseInt(conf.get("topology.bolt.parallel"), 2);
        // 聲明bolt
        BoltDeclarer bolt = topologyBuilder.setBolt(SimpleBolt.NAME, new SimpleBolt(), boltParallel);

        bolt.localOrShuffleGrouping("simple-spout","stream-id");

    }

    /**
     * 配置參數
     */
    private static Map conf = new HashMap<String, Object>();

    /**
     * 本地運行模式
     * @param conf 配置
     * @throws InterruptedException 異常
     */
    private static void runLocalMode(Map<String, Object> conf) throws InterruptedException{
        try {
            TopologyBuilder builder = new TopologyBuilder();
            LocalCluster cluster = new LocalCluster();
            SimpleTopology.defineTopology(builder, conf);
            logger.info("commit Topology ...");

            cluster.submitTopology(topologyName, conf, builder.createTopology());
            logger.info("commit Topology finish, sleep 600000");
            Thread.sleep(600000);
            cluster.killTopology(topologyName);
            cluster.shutdown();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 遠程運行模式
     * @param conf 配置
     * @throws AlreadyAliveException
     * @throws InvalidTopologyException
     */
    private static void runRemoteMode(Map<String, Object> conf) throws AlreadyAliveException, InvalidTopologyException {
        TopologyBuilder builder = new TopologyBuilder();

        SimpleTopology.defineTopology(builder, conf);

        StormSubmitter.submitTopology(topologyName, conf, builder.createTopology());
    }





    /**
     * 加載配置.
     * @param arg 配置文件
     */
    private static void LoadConf(String arg) {
        if (arg.endsWith("yaml")) {
            conf = LoadConf.LoadYaml(arg);
        } else {
            conf = LoadConf.LoadProperty(arg);
        }
    }

    /**
     *  加載本地參數.
     * @param conf 配置
     * @return 返回true說明加載的是本地的參數
     */
    private static boolean local_mode(Map conf) {
        String mode = (String) conf.get(Config.STORM_CLUSTER_MODE);
        if (mode != null) {
            if (mode.equals("local")) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        // 本地測試
        String config = ConfigUtils.class.getResource("/topology-local.yaml").getFile();

        // 集羣配置
//        if (args.length == 0) {
//            logger.error("Please input configuration file");
//            System.exit(-1);
//        }
//        String config = args[0];
        // 加載配置文件,判斷是本地模式還是集羣模式
        LoadConf(config);

        try {
            if (local_mode(conf)) {
                System.out.println(" loading local ...");
                logger.info(" loading local ... ");
                runLocalMode(conf);
            } else {
                runRemoteMode(conf);
            }
        }catch (InterruptedException e) {
            logger.error("InterruptedException ", e);
        }
        catch (AlreadyAliveException e) {
            logger.error("AlreadyAliveException ", e);
            e.printStackTrace();
        }catch (InvalidTopologyException e) {
            logger.error("InvalidTopologyException ", e);
            e.printStackTrace();
        }
    }

提交topology

  1. 將定義好得代碼打包成jar
  2. 然後執行以下命令,在部署的jstorm環境中提交jar,上篇jstorm環境搭建中,在hd-23服務器上登錄jstorm用戶,將jar放到用戶目錄下,執行以下命令即可。
# 
jstorm jar hollyvoc-data-topology.jar com.hollycrm.hollyvoc.app.KafkaApplication  topology-remote.yaml 
# hollyvoc-data-topology.jar 是jar包的名稱
#  com.hollycrm.hollyvoc.app.KafkaApplication 程序運行的主類
# topology-remote.yaml 配置文件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章