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中的数据,这样就不会产生不可预知的问题了。如果你熟悉函数式语言(不可变对象),这点应该不用多说。

 

你可能感兴趣的:(storm笔记 进程内和进程间emit的区别)