Apache STORM工作原理详解

Apache Storm是一个分布式实时计算系统,允许用户在集群上运行流式数据处理应用程序。它的核心原理是将流式数据分割成多个小块,每个小块都会被分配给不同的计算节点进行处理,并且处理结果会被发送到下一个节点,直到达到最终结果。以下是Apache Storm的工作原理:

  1. Nimbus 是整个集群的控管核心,负责topology的提交、运行状态监控、任务重新分配等工作。zk就是一个管理者,监控者。总体描述:nimbus下命令(分配任务),zk监督执行(心跳监控worker、supurvisor的心跳都归它管),supervisor领旨(下载代码),招募人马(创建worker和线程等),worker、executor就给我干活!task就是具体要干的活。

  2. Storm集群中有两类节点:主控节点(Master Node)和工作节点(Worker Node)。其中,主控节点只有一个,而工作节点可以有多个。

  3. Nimbus进程与Supervisor进程 主控节点运行一个称为Nimbus的守护进程类似于Hadoop的JobTracker。Nimbus负责在集群中分发代码,对节点分配任务,并监视主机故障。
    每个工作节点运行一个称为Supervisor的守护进程。Supervisor监听其主机上已经分配的主机的作业,启动和停止Nimbus已经分配的工作进程。

  4. Topology 在Apache Storm中,用户需要定义一个叫做“Topology”的概念,表示数据流处理的整个计算流程。Topology可以看做是一个有向无环图(DAG),其中每个节点表示一个数据处理任务,每个边表示数据的流动。

  5. Spout Spout是Topology中的数据源,用来读取外部数据并将其转换为数据流。Spout可以从文件、消息队列、数据库等数据源中读取数据。Spout读取数据后,会将其分成多个小块(Tuple),并将每个小块发送到Topology中的第一个节点。

  6. Bolt Bolt是Topology中的计算节点,用来对数据进行处理。每个Bolt节点接收一个或多个输入Tuple,并对其进行处理后输出一个或多个新的Tuple。Bolt可以进行过滤、转换、聚合等各种数据处理操作。

  7. Stream Grouping Stream Grouping是指Topology中每个节点输出Tuple时如何将其发送给下一个节点。Stream Grouping可以按照不同的方式进行配置,比如随机分配、轮询分配、广播等。Stream Grouping可以确保数据流在不同节点之间的负载均衡,同时也可以保证数据的顺序和一致性。

  8. Task Task是指Topology中实际运行的计算单元,每个Task对应一个计算节点或线程。每个Task运行时会从Spout或Bolt节点中接收数据,并按照Stream Grouping规则将其发送到下一个节点。Task还可以进行数据的本地缓存、聚合等优化操作,以提高计算效率。

  9. Storm Cluster Storm Cluster是指一组运行Storm的服务器集群,可以包含数十甚至上百个节点。Storm Cluster负责调度和管理Topology中的各个计算节点,并确保它们在集群中的分布式运行。

总之,Apache Storm通过拆分流式数据、实现分布式计算、优化数据流动方式等多种方式来实现高效、可靠的实时计算。
 

在Apache Storm中,Executor线程和Task是一种父子关系,一个Executor线程可以同时运行多个Task。通常是一个Executor线程运行一个Task。一个Task是Storm中的最小计算单元,它实际上是由Executor线程来执行的。每个Task都会被分配给一个Executor线程来运行,Executor线程在运行过程中会处理多个Task,并负责管理它们的生命周期。

另外,Task和Component之间也有一种父子关系。在Storm中,Topology由多个Component组成,每个Component对应一个Spout或Bolt。每个Component都可以包含多个Task,这些Task都会共享相同的Component实例和配置信息。例如,一个Bolt Component可能会包含多个Task来处理不同的输入Tuple。不同的Component之间通过Stream Grouping规则进行连接,从而构成Topology中的完整数据流处理流程。

因此,Executor线程和Task之间的关系是一种父子关系,Executor线程负责管理和运行多个Task。Task和Component之间的关系也是一种父子关系,Component负责管理和配置多个Task。通过这些关系,Storm能够高效地管理和调度多个Task,并将它们组合成复杂的数据处理流程。

每个Executor线程实际上都是一个线程,而不是线程池。每个Worker进程包含多个Executor线程,每个Executor线程都是一个独立的线程。每个Executor线程只能同时执行一个Task,但由于多个Executor线程同时运行在同一个Worker进程中,因此可以实现多个Task的并行处理。

每个Worker进程会根据配置信息创建多个Executor线程。例如,如果在一个Worker进程中配置了4个Executor线程,那么该Worker进程就会创建4个线程,每个线程可以同时运行一个Task。每个线程都是一个独立的执行单元,它们可以并行地执行不同的Task。由于每个Worker进程可以运行多个Executor线程,因此可以同时处理多个Task,提高Storm的处理性能和吞吐量。

在Apache Storm中,setNumTasks()是一个TopologyBuilder中的方法,用于设置一个Bolt或Spout组件的Task数量。可以通过该方法来控制每个组件并行处理的Task数量,从而优化Storm的性能和吞吐量。

具体来说,setNumTasks()方法会将指定组件的并行处理任务数量设置为一个固定值。例如,如果将一个Bolt组件的Task数量设置为10,那么Storm将会为该Bolt创建10个Task实例,并将输入Tuple分配给这10个Task来并行处理。这样可以将一个组件的处理能力分摊到多个Task中,提高处理性能和吞吐量。

需要注意的是,setNumTasks()设置的是组件的Task数量,而不是线程或进程数量。每个Task都会运行在一个单独的线程中,并且可以在同一个Worker进程中运行多个Task,从而实现多个Task的并行处理。因此,组件的Task数量不一定等于线程或进程数量,具体取决于Worker进程和Executor线程的配置。

在使用setNumTasks()方法时,需要根据实际情况和系统资源的限制来合理设置组件的Task数量。如果设置的数量太少,可能会导致处理性能不足;如果设置的数量太多,则可能会浪费系统资源并影响性能。可以根据实验和测试结果来逐步调整Task数量,找到一个最优的设置。

三、并行度

(一)storm拓扑的并行度可以从以下4个维度进行设置:

1、node(服务器):指一个storm集群中的supervisor服务器数量。
2、worker(jvm进程):指整个拓扑中worker进程的总数量,这些数量会随机的平均分配到各个node。
3、executor(线程):指某个spout或者bolt的总线程数量,这些线程会被随机平均的分配到各个worker。
4、task(spout/bolt实例):task是spout和bolt的实例,它们的nextTuple()和execute()方法会被executors线程调用。除非明确指定,storm会给每个executor分配一个task。如果设置了多个task,即一个线程持有了多个spout/bolt实例.
注意:以上设置的都是总数量,这些数量会被平均分配到各自的宿主上,而不是设置每个宿主进行多少个进程/线程。详见下面的例子。

(二)并行度的设置方法

1、node:买机器吧,然后加入集群中……
2、worker:Config#setNumWorkers() 或者配置项 TOPOLOGY_WORKERS
3、executor:Topology.setSpout()/.setBolt()
4、task:ComponentConfigurationDeclarer#setNumWorker()

(三)示例

// 创建topology  
TopologyBuilder builder = new TopologyBuilder();  
builder.setSpout("kafka-reader", new KafkaSpout(spoutConf), 5);//设置executor数量为5  
builder.setBolt("filter-bolt", new FilterBolt(), 3).shuffleGrouping(  
        "kafka-reader");//设置executor数量为3  
builder.setBolt("log-splitter", new LogSplitterBolt(), 3)  
        .shuffleGrouping("filter-bolt");//设置executor数量为5  
builder.setBolt("hdfs-bolt", hdfsBolt, 2).shuffleGrouping(  
        "log-splitter");//设置executor数量为2  
  
// 启动topology  
Config conf = new Config();  
conf.put(Config.NIMBUS_HOST, nimbusHost);  
conf.setNumWorkers(3);      //设置worker数量  
StormSubmitter.submitTopologyWithProgressBar(topologyName, conf,  
        builder.createTopology());  

1、通过config.setNumWorkers(3)将worker进程数量设置为3,假设集群中有3个node,则每个node会运行一个worker。
2、executor的数量分别为:
spout:5
filter-bolt:3
log-splitter:3
hdfs-bolt:2
总共为13个executor,这13个executor会被随机分配到各个worker中去。
注:这段代码是从kafka中读取消息源的,而这个topic在kafka中的分区数量设置为5,因此这里spout的线程ovtn为5.
3、这个示例都没有单独设置task的数量,即使用每个executor一个task的默认配置。若需要设置,可以:

        builder.setBolt("log-splitter", new LogSplitterBolt(), 3)
                .shuffleGrouping("filter-bolt").setNumTasks(5);

来进行设置,这5个task会被分配到3个executor中。

(四)并行度的动态调整
对storm拓扑的并行度进行调整有2种方法:
1、kill topo—>修改代码—>编译—>提交拓扑
2、动态调整
第1种方法太不方便了,有时候topo不能说kill就kill,另外,如果加几台机器,难道要把所有topo kill掉还要修改代码?
因此storm提供了动态调整的方法,动态调整有2种方法:
1、ui方式:进入某个topo的页面,点击rebalance即可,此时可以看到topo的状态是rebalancing。但此方法只是把进程、线程在各个机器上重新分配,即适用于增加机器,或者减少机器的情形,不能调整worker数量、executor数量等
2、cli方式:storm rebalance
举个例子

storm rebalance toponame -n 7 -e filter-bolt=6 -e hdfs-bolt=8

将topo的worker数量设置为7,并将filter-bolt与hdfs-bolt的executor数量分别设置为6、8.
此时,查看topo的状态是rebalancing,调整完成后,可以看到3台机器中的worker数量分别为3、2、2

你可能感兴趣的:(apache,storm,java)