您的位置:首页 > 大数据

大白话storm

2014-04-16 16:08 831 查看
[b]白话storm[/b]
storm介绍网络上已经有很多版本了,但建议大家去看官方文档,有些问题上网一搜,好吧,作者的回答我觉得不全对,所以避免被误导,建议大家去官网学习,那我这里主要谈下我对storm的理解。

[b]个人理解:storm是一个分布式、实时、流、计算、平台,几个特性从这名字中已经看出来了。[/b]
一、实时,简单理解就是数据进入系统要迅速被处理,也就是延迟要小。

二、流,流具有什么特点,想象一下你站在长江岸边,什么感觉,震撼?浩荡?小弟没看过,我理解的流就是①没有阻塞②方向只能从高到低③流之间没有影响④可以灵活改变流的方向(挖个沟,对应storm的grouping机制) ⑤不间断
三、计算,这个概念其实比较广,计算机处理任何东西一般都涉及计算,在这里我理解的还是没有阻塞,也就是更倾向于计算,不要和外部过多资源进行交换,例如网络、磁盘。。。

四、分布式,分布式大家听的耳朵都起茧子了,个人有个人的理解,分布式一个比较重要的衡量指标就是可扩展性(线性、非线性)、资源对服务或用户透明、具有一定的负载均衡能力、充分利用资源?(好像国内好多搞hadoop的都用牛逼服务器,貌似hadoop出来是为了利用那些过时老旧的机器的)、最好是无序。。。

五、平台,这个好理解,它就是提供了以上四个主要特性的平台,那满足这个平台要求的服务就可以在这个平台上跳舞,一个好的平台可以改变我们的命运哦~

六、可靠性,分布式系统那么多组件,某个出现了问题storm可以自动恢复

[b]适应场景[/b]
从以上5点可以总结出storm注重的是实时性、偏重计算、分布式特性、线性可扩展、流的特性。当然有了这些特性最终还是要靠到业务逻辑上,这个我写过一篇基于storm做爬虫的可能性,我觉得在爬虫的场景里边,用storm是再好不过的了,因为爬虫一般是7*24小时不间断的从网络上获取数据,构成了流,一般还要求实时性,就是尽快将最新的内容搞到自己的口袋里,计算量也不小涉及到各种数据的处理,然后遇到瓶颈后可以平滑的进行线性可扩展,无需停止服务,最主要一点是爬虫种子间处理没什么关联,完全切合分布式的特性,总之等等吧,我觉得如果把爬虫放到storm上犹如杨过获得了一把屠龙刀。

[b]注意几点(实践出真知?)[/b]

一个worker被kill情况下,假如这个worker和其它worker没有关系,貌似其它worker不会受影响,被kill的worker会被storm启动,若和其它worker有关系,那么其它worker也会受影响,task会被重新启动(类似于rebalance的效果,好像和rebalance的过程一样)。

acker貌似是就近原则,一个spout的消息优先采用本地acker跟踪,经测试效果看,一旦acker被kill,当这个acker再次被启动的时候,其之前跟踪的那些消息将迅速失败。

acker无法被rebalance。

大家都知道storm中nextTuple和ack或fail方法是在一个线程下执行的,经测试观察,storm会先调用spout的nextTuple()然后再检查ack(mid)或fail(mid),再配合storm的pending机制,这个大家有时需要注意,在特定的需求下可能会有类似于死锁的问题。(这里不详细说明,如有需要可以留言给我,因为只是在我们的特定需求上出现过问题)。

storm虽然不建议大家在bolt或spout中new新的线程,但有时为了异步处理,也是不可避免的,经测试观察,storm自己启动的线程优先级比较高,假若你想自己的线程得到充分调用需要设置自己创建的线程优先级到更高(我一般直接到最大了,然后用lock机制,然后windows和类UNIX系统jvm线程优先级是有差别的,这个大家可以去深入了解下)。

因为不同的机器可能资源不同,storm默认调度器机制基本是平均分配机制,这会导致,数据乱序情况比较严重。

storm先启动你的spout然后再依次启动不同机器上的bolt task,spout不会等bolt都启动完成后才开始发数据,这时假如你有一个bolt初始化耗费1分钟,然后你的消息超时设置的是30s,那在这个bolt启动完成之前的消息会因为spout超时设置的比较短而导致消息超时,从而导致spout fail(mid)。 好吧,我承认这个我之前理解错了,storm会执行spout的open和各个bolt的prepare,依次都初始化好后会激活spout(Activate spout),这时spout工作线程才开始执行nextTuple。

topology的TOPOLOGY_RECEIVER_BUFFER_SIZE设置成16会比较快,至少在我们业务上整体速度在1w+这个速度下,设置成16比8或32要快,当然不同的场景这个值可能会不同(这里要强调一下,storm中有四个buffer,理解起来比较别扭,而且四个buffer不是收/发对称的,还是推荐大家去看官方文档或权威一点的地去学习)

先这么多。。。想起什么了,后期再补充

bolt处理错误不好往spout传,也就是一个tuple处理失败了,spout端只能知道失败的消息的id,而不知道具体失败的原因,这块儿我觉得不是很灵活,当然要是在一个worker下不会有这种问题,只出现在分布式环境下。

bolt emit一个tuple虽然可以anchor(锚定)到一个list<Tuple>,但是collector的ack或fail方法只能接收单个tuple,不能直接ack/fail一个list<Tuple>,如下代码:

collector.emit(TopoUtil.StreamId.DEFAULT,
list,
new Values(sonSMessage));

for (Tuple tuple : list) {
collector.ack(tuple);
}


storm rebalance 经测试看有点问题,就是-n参数只能从一开始提交的进程数rebalance到更小,不能从2rebalance到3 或4 或更大,-e参数没有这个问题,但线程数是不能大于task数的,这个弄过storm都知道,前面需要注意

以上均是个人理解,有些是查了文档,有些完全是工程实践,现象观察总结的,不能保证完全正确,有歧义的地方大家可以积极评论,小弟也一直在学习,望共同进步,我这个分享也是抛砖引玉,希望大神不要吝啬自己的知识,拿出来多和大家分享分享!!!

祝大家工作顺利,天天开心!

jerry 于2014.04.16 16:00
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息