Storm的实时性可能主要体现在:
1.相比Hadoop,Storm是为实时处理而设计的;
2.Storm的Topology启动后,一直处理就绪状态,等待数据输入,一旦有数据会立即处理;这一点不同于Hadoop,Hadoop每处理一个Job都需要重新提交,而且对于实时到来的数据也无法立即处理。“Storm中流动的是数据,Hadoop中流动的是代码”,这个说法很精辟。
3.Storm在处理过程中基于Stream,不写文件和数据库,而且使用ZeroMQ传递消息(传说中最快的MQ),所以处理速度很快,自然也提高了实时性;
任务级失败
1.Bolt任务crash引起的消息未被应答。此时,acker中所有与此Bolt任务关联的消息都会因为超时而失败,对应的Spout的fail方法将被调用。
2.acker任务失败。如果acker任务本身失败了,它在失败之前持有的所有消息都将超时而失败。Spout的fail方法将被调用。
3.Spout任务失败。在这种情况下,与Spout任务对接的外部设备(如MQ)负责消息的完整性。例如,当客户端异常时,kestrel队列会将处于pending状态的所有消息重新放回队列中。
storm的容错保障机制:
任务槽(slot)故障
1.Worker失败。每个Worker中包含数个Bolt(或Spout)任务。Supervisor负责监控这些任务,当worker失败后会尝试在本机重启它,如果它在启动时连续失败了一定的次数,无法发送心跳信息到Nimbus,Nimbus将在另一台主机上重新分配worker。
2.Supervisor失败。Supervisor是无状态(所有的状态都保存在Zookeeper或者磁盘上)和快速失败(每当遇到任何意外的情况,进程自动毁灭)的,因此Supervisor的失败不会影响当前正在运行的任务,只要及时将他们重新启动即可。
3.Nimbus失败。Nimbus也是无状态和快速失败的,因此Nimbus的失败不会影响当前正在运行的任务,但是当Nimbus失败时,无法提交新的任务,只要及时将它重新启动即可。
集群节点(机器)故障
1.Storm集群中的节点故障。此时Nimbus会将此机器上所有正在运行的任务转移到其他可用的机器上运行。
2.Zookeeper集群中的节点故障。Zookeeper保证少于半数的机器宕机系统仍可正常运行,及时修复故障机器即可。
Nimbus是否是“单点故障”的
如果失去了Nimbus节点,Worker也会继续执行。另外,如果worker死亡,Supervisor也会继续重启他们。但是,没有Nimbus,Worker不会在必要时(例如,失去一个Worker的主机)被安排到其他主机,客户端也无法提交任务。
所以Nimbus“在某种程度上”是单点故障。在实践中,这不是一个大问题,因为Nimbus守护进程死亡,不会发生灾难性问题。
storm中,ack与fail信息的处理
spout和bolt的实现需要继承或者实现接口。对于spout来说,有两个基类以供继承:BaseBasicSpout和BaseRichSpout。两个类的区别是:前者隐式的传递了ack和fail信息,系统会自动传递,然后自动处理;而后者,需要我们手动的去调用ack和fail信息,以供我们后续去自定义ack和fail的要响应的内容。
现在看到,若要实现手动的编写ack及fail的响应方法,继承上述的两个基类均可以,但同时需要注意的必须要做的有两点:
1,、需要在spout中覆写ack及fail方法:如
/**
* 成功处理
*/
public void ack(Object msgId) {
System.out.println("ack++++++++++++++++++++++++++++++++ack");
}
/**
* 失败处理
*/
public void fail(Object msgId) {
System.out.println("fail++++++++++++++++++++++++++++++++fail");
}
2、需要在spout向后续的bolt发射tuple时,需要指定一个messageId,如
Values value=new Values(list.get(j)));
_collector.emit(new Values(value,value);//在这里,messageid就是value本身
一般情况下,可以使用value本身作为这个messageid。这样就将这个value和它的id进行了anchor.同时,在后续的bolt在接收这个tuple后,除了可以进行处理并向下发送外,还需将这个tuple进行ack。也就如下:
//处理tuple,比如将tuple处理后的结果为data
Values value=new Values(data);
collector.emit(tuple,value);//tuple为本次execute方法接收的tuple,而value则是将tuple进行改变后生成的data值。这个过程就是进行anchor
collector.ack(tuple);//对tuple进行ack消息回送
每当tuple向节点的子节点进行分发的时候,tuple所对应的messageId都会进行一定的异或运算。然后在最后树结构完成后,异或的结果若是0,则说明处理过程是成功的,则调用ack方法;若超时,则调用fail方法。
Storm DRPC 使用
Storm是一个分布式实时处理框架,它支持以DRPC方式调用.可以理解为Storm是一个集群,DRPC提供了集群中处理功能的访问接口.
其实即使不通过DRPC,而是通过在Topoloye中的spout中建立一个TCP/HTTP监听来接收数据,在最后一个Bolt中将数据发送到指定位置也是可以的。而DPRC则是Storm提供的一套开发组建,使用DRPC可以极大的简化这一过程。
DRPC包括服务端和客户端两部分:
服务端
服务端由四部分组成:包括一个DRPC Server, 一个 DPRC Spout,一个Topology和一个ReturnResult。
DRPC Server:实现与客户端的对接,传递参数给Storm,返回结果给客户端。
DPRCSpout: 用于连接DRPC Server和Topology,传递参数给Topology。
Topology:实现实际的函数功能。
ReturnResults:用于连接DRPC Server和Topology,用于返回参数给DRPC Server。
客户端:用来发起DRPC的调用
流程描述如下:
客户端发送函数的参数给DRPC Server
DRPC Server生成发送函数调用的相关信息给DRPC Spout,包括请求ID,请求参数,返回结果的信息。
DRPC Spout发送[“id”, “request”]给Topology的第一个Bolt,其中id代表请求ID,request代表请求参数。
Topology最后一个Bolt发送[“id”, “result”]给ReturnResults,其中id代表请求ID,result代表返回结果
ReturnResults将请求ID和结果传递给DRPC Server
DRPC Server将结果返回给DRPC客户端。
Storm DPRC API介绍
我们先看一下DRPC客户端的API:
DRPCClient client = new DRPCClient(“drpc-host”, 3772);
String result = client.execute(“reach”, “http://twitter.com”);
先构建一个DRPCClient对象,代表DRPC客户端。第一个参数是主机地址,第二个参数为端口号。
然后用这个client调用execute函数,远程执行函数。execute第一个参数表示函数名称,第二个参数为函数参数。
我们再来看一下DRPC服务器端的API:
本地模式的DRPC:
LinearDRPCTopologyBuilder builder = new LinearDRPCTopologyBuilder("exclamation");
builder.addBolt(new ExclaimBolt(), 3);
LocalDRPC drpc = new LocalDRPC();
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("drpc-demo", conf, builder.createLocalTopology(drpc));
System.out.println("Results for 'hello':" + drpc.execute("exclamation", "hello"));
cluster.shutdown();
drpc.shutdown();
LinearDRPCTopologyBuilder用来生成一个builder,参数用来指定函数的名字,也就是你在客户端调用execute时,指定的函数名字。用builder来构建topology
LocalDRPC用来构建一个本地的DRPC Server。
LocalCluster用来构建本地的集群
builder.createLocalTopology(drpc)时需要指定一个DRPC Server,用来让Storm知道DRPC Server的信息。
远程模式的DRPC:
StormSubmitter.submitTopology("exclamation-drpc", conf, builder.createRemoteTopology());
远程模式的DRPC与本地模式的DRPC不同之处在于:
远程模式DRPC不需要模拟DRPC Server,而是通过在真实的Storm集群中配置DRPC Server来完成
远程模式通过调用builder的createRemoteTopology方法来构建topology。
Trident DRPC API介绍
Trident DRPC的客户端和普通Storm的DRPC客户端一样
Trident DRPC服务端API介绍
TridentTopology topology = new TridentTopology();
topology.newDRPCStream("words")
.each(new Fields("args"), new Split(), new Fields("word"))
.groupBy(new Fields("word"))
.stateQuery(wordCounts, new Fields("word"), new MapGet(), new Fields("count"))
.each(new Fields("count"), new FilterNull())
.aggregate(new Fields("count"), new Sum(), new Fields("sum"));
消息组件—kafka概念详述
kafka基本概述
具有发布和订阅消息流,以容错的方式记录消息流,以文件的方式来存储消息流,可以在消息发布的时候进行处理。简而言之,kafka的功能就是实时流的管道,实时流的处理
kafka集群有多个Broker服务器组成,每个类型的消息被定义为topic。
同一topic内部的消息按照一定的key和算法被分区(partition)存储在不同的Broker上。
消息生产者producer和消费者consumer可以在多个Broker上生产/消费topic
概念理解:
Topics and Logs:
Topic即为每条发布到Kafka集群的消息都有一个类别,topic在Kafka中可以由多个消费者订阅、消费。
每个topic包含一个或多个partition(分区),partition数量可以在创建topic时指定,每个分区日志中记录了该分区的数据以及索引信息。如下图:
Kafka只保证一个分区内的消息有序,不能保证一个主题的不同分区之间的消息有序。如果你想要保证所有的消息都绝对有序可以只为一个主题分配一个分区。
分区会给每个消息记录分配一个顺序ID号(偏移量), 能够唯一地标识该分区中的每个记录。Kafka集群保留所有发布的记录,不管这个记录有没有被消费过,Kafka提供相应策略通过配置从而对旧数据处理。
实际上,每个消费者唯一保存的元数据信息就是消费者当前消费日志的位移位置。位移位置是由消费者控制,即、消费者可以通过修改偏移量读取任何位置的数据。
1、Producer:消息和数据的生产者,向kafka的一个topic发布消息的进程/代码/服务,在发送消息之前,会对消息进行分类,即Topic
2、Consumer:消息和数据的消息者,订阅数据(Topic)并且处理kafka集群发布消息的进程/代码/服务
3、Consumer Group:消费者组,一个consumer group包含多个consumer,用户可以指定consumer的group,各个consumer可以组成一个group,每个消息只能由一个group中的一个consumer消费,如果一个消息想要被多个consumer消费,这些consumer必须在不同的group中
4、Broker:kafka集群中的每个kafka节点
5、Topic:kafka的消息类别,对数据进行区分和隔离
6、Partition:topic物理上的分组,一个topic可以分为多个partition,topic下的数据会被分散存储到多个partition,每个partition是一个有序队列
7、Replication(副本):同一个partition可能会有多个Replication,多个副本之间的数据是一样的
8、Replication Leader:
9、Segment:partition物理上由多个segment组成,每个segMent存在着message信息