jstorm学习笔记--初识(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34503659/article/details/78913783

什么是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 配置文件

猜你喜欢

转载自blog.csdn.net/qq_34503659/article/details/78913783