版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34503659/article/details/78913783
什么是jstorm
基本概念
元组(tuple)
jstorm 消息传递的基本单位,是一个命名的值列表,元组中的字段可以是任何类型的。支持所有的基本类型、字符串和字节数组,也支持自定义的序列化接口对象。
流(stream)
数据之间通过流进行传递,是核心抽象。流有元组组成,实质是元组序列。
龙卷(spout)
拓扑中流的来源,即数据的来源。
- 闪电(bolt)
流的处理节点,即接受到spout流出的数据并进行处理。
- 流分组(Stream grouping)
spout和bolt、bolt和bolt之间数据如何分发和接受,通过流分组定义。流分组定义了流/元组如何在bolt任务之间分发。 拓扑(topology)
各组件的消息流动形成逻辑上的拓扑结构,是jstorm中一个实时应用程序。类似于MapReduce 的作业。拓扑与MapReduce的区别在于,后者的作业始终会完成,而拓扑会永远运行知道他被kill。
工作进程(worker)
- 任务(task)
- 执行器(executor)
- 主空节点和工作节点
集群有主控节点(MasterNode)和工作节点(Worker Node) ,主控节点只有一个,工作节点有多个。 - nimbus进程和supervisor进程
主控节点运行nimbus进程,类似hadoop的jobTracker,用来在集群中分发jar,对节点进行任务分配,并检测主机故障。工作节点运行supervisor进程,监听主机分配的作业。
==总结:==
jstorm 的各组件关系,可以用一句话来概括:
一个topology 包含多个spout和bolt ,bolt和spout的基本单位是tuple,spout 和bolt、bolt和bolt之间通过stream传递数据。数据的传递和接受规则通过流分组实现。
如何创建一个简单的topology
创建一个简单的topology- 实现spout接口
数据处理的数据来源,接受数据 - 实现bolt接口
从spout中接受数据进行逻辑处理 - 生成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
- 将定义好得代码打包成jar
- 然后执行以下命令,在部署的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 配置文件