<div class="articalContent newfont_family" id="sina_keyword_ad_area2">
<div style="">
<div>
<strong>本文继<a href="http://blog.sina.com.cn/s/blog_7ea3d46f0101ligt.html" rel="noopener noreferrer" target="_blank">《Strom流计算编程模型》</a>之后继续介绍Storm上层高级批处理抽象Trident。</strong>
</div>
<div>
<strong>(五)高级抽象</strong>
</div>
<div>
<strong>1、Trident State</strong>
</div>
<div>
Storm是对实时流计算的分布式处理框架,在对Stream中封装的Tuple处理过程中涉及到很多中间过程对Tuple进行存储、查询、更新、聚合、分组等变化,Storm的高级抽象Trident将这些变化封装为TridenState对象,使得Trident可以很容易的进行Functions、Filters、partitionAggregate、partitionPersist、projection、Merges、joins等处理。
</div>
<div>
<span style="font-family:Microsoft Yahei">Trident以容错的方式管理状态State,保证所有的元组Tuple被准确可靠的只处理一次,并可以将State持久化<span style="background-color:rgb(255,255,255)"><span style="color:#333333">保留在</span><u><span style="color:#FF0000">topology的内部</span></u><span style="color:#333333">,比如说内存和HDFS,也可以放到</span><u><span style="color:#FF0000">外部存储</span></u><span style="color:#333333">当中,比如说Memcached或者Cassandra。这些都是使用同一套TridentAPI。</span></span> <wbr></wbr></span>
</div>
<div>
假若没有TridentState,那么在灾难故障发生时,应用可能对Tuple的状态不知所措,不清楚该该流入的Tuple是否已经过处理,并成功更新了状态。这里以WordCount举例,当故障发生时,Tuple流被重放,那么对此Tuple流的处理情况将产生疑惑,比如:
</div>
<div>
1)若此Tuple流从未被成功处理过,需要进行Counter统计;
</div>
<div>
2)若此Tuple流已经完成Counter统计环节,但在其他环节发生故障,那么不应该再次对此Tuple进行Counter统计;
</div>
<div>
3)若此Tuple流已经完成整个Counter统计处理,但是在对外部数据库保存时,外部数据库发生故障,那么只应该更新数据库,Tuple树不应再进行处理。
</div>
<div>
Trident解决上述问题设计完全取决于对Spout的封装,对Spout的容错设计如下:
</div>
<div>
<div>
1) Tuple元组流通过批来处理
</div>
<div>
2)
<wbr></wbr>每一批元组都有唯一的事务txid,如果这个批因故障被重放,将会拥有之前相同的txid
</div>
<div>
3)
<wbr></wbr>State更新在批中是强制有序的,也就是说批3对应的状态更新一定会在批2的状态更新成功之后再去执行
</div>
</div>
<div>
Trident每个批处理都有三类Spout发射流:non-transactional、transactional、opaquetransactional,因此与之对应的TridentState也有non-transactional、transactional、opaquetransactional三类。而Storm默认的Spout只是实现了IRichSpout,这是一个不带任何事务,并且非批处理的输入发射流。因此,Trident封装了以下几种Spout:
</div>
<div>
<div>
<ul><li>ITridentSpout: 最常用的接口,可支持强制事务transactional <wbr></wbr>和不透明的事务 opaquetransactional <wbr></wbr>批处理发射流</li><li>IBatchSpout: <wbr></wbr>不带任何事务的批处理发射流</li><li>IPartitionedTridentSpout<wbr></wbr>: <wbr></wbr>强制事务 <wbr></wbr>transactional <wbr></wbr>批处理发射流</li><li>IOpaquePartitionedTriden<wbr></wbr>tSpout: <wbr></wbr>不透明的事务 <wbr></wbr>opaquetransactional <wbr></wbr>批处理发射流</li></ul>
</div>
</div>
<div>
<u>1)Transactionalspouts</u>:一个Tuple只会在一个batch中;各个batch之间是没有交集,每个tuple只能属于一个batch;所有Spout发射的Tuple都在batch中,不会有任何遗漏。但Transactionalspouts不足之处是一旦绑定的数据流发射源故障,那么对Tuple的处理将会被挂起。这也就是"opaquetransactional" spouts(不透明事务spout)存在的原因-他们对于丢失源节点这种情况是容错的,仍然能够帮你达到有且只有一次处理的语义。
</div>
<div>
举例说明Transactional spouts的语义,假设数据库当前记录如下:
</div>
<div>
<pre style="overflow:auto; word-wrap:normal; margin-bottom:15px; font-size:13px; border-top:rgb(221,221,221) 1px solid; font-family:Consolas,'Liberation Mono',Courier,monospace; border-right:rgb(221,221,221) 1px solid; border-bottom:rgb(221,221,221) 1px solid; color:rgb(51,51,51); padding-bottom:6px; font-style:normal; padding-top:6px; padding-left:10px; border-left:rgb(221,221,221) 1px solid; margin-top:15px; line-height:19px; padding-right:10px; background-color:rgb(248,248,248)"><span style="font-family:Consolas">man <span style="font-weight:bold">=></span> [count<span style="font-weight:bold">=</span><span style="color:rgb(0 |
|