storm笔记 进程内和进程间emit的区别

  我们都知道,storm当中,对于进程内的task通信,和进程间的通信使用的是不同的机制。进程间的通信使用的是nio(目前默认是netty),而进程内的通信使用的是disruptor做线程间共享。当我们emit一条消息时,是没有办法知道消息会被发送到什么地方去的,所以这个区别理论上是对上层开发者透明的。但是实际上,这两种情况对应用的开发还是有影响的,这里记录下本人发现的几点问题:

 

1. 当work进程数目大于1时,task线程有可能就会分布在不同的进程中。这时我们emit出去的对象必须实现Serializable接口,否则会报错,因为进程间的tuple发送和接收使用的是序列化的对象。而在同一woker中的话不存在这个问题。

2.当emit的下一跳是同进程的另一线程时,tuple是通过引用共享被下游task获取到的。因此,如果在上下游都对同一个tuple做修改的话,可能会导致并发问题。与上面相反,上下游task位于多个进程的情况下不会有这个问题,因为对象引用并不会共享。

 

  但是,值得注意的是,tuple被emit的去向对我们来说是不可控制的。因此,在开发中我们应该注意:

1. emit的自定义对象,需要实现Serializable接口, 因为谁也无法保证它是否会被反序列化发送到另一个进程。

2. 对于emit的对象类型数据,要考虑线程安全问题。原则上不应该修改tuple中的数据,这样就不会产生不可预知的问题了。如果你熟悉函数式语言(不可变对象),这点应该不用多说。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值