流分组为每一个Bolt指定应该接受哪个流作为输入,定义了流/元组如何让在Bolt的任务之间进行分发。
在设计拓扑的时候,需要做一件非常重要的事情,就是定义数据如何在组件之间进行的交换。一个流分组指定每个Bolt消耗哪个流,流将如何被消耗。一个节点可以发出许多流,流分组允许我们有选择地接受流。
Storm内置了7种流分组方式,通过实现CustomStreamGrouping接口可以实现自定义的分组。
1.随机分组(ShuffleGrouping)
它是最常用的流分组方式,它随机的分发元组到Bolt上的任务,这样就保证每个任务得到相同数量地元组。
代码:public T shuffleGrouping(String componentId);
public T shuffleGrouping(String componentId,String streamId);
2.字段分组(Fields Grouping)
字段分组根据指定字段对流进行分组。例如,如果流是按照user-id字段进行分组,具有相同的user-id的元组总是被分发到相同的任务,具有不同的user-id的元组被分发到不同的元组。字段分组是实现流连接和关联,以及大量其他用力的基础。在现实中,字段分组利用取模散列来实现。
代码: public T fieldsGrouping(String componentId,Fields fields);
public T fieldsGrouping(String componentId,String streamId,Fields fields);
3.广播分组(AllGrouping)
它是指流被发送到所有的Bolt的任务中,使用这个分组时要小心。
代码:public T allGrouping(String componentId);
public T allGrouping(String componentId,String streamId);
4.全局分组(GlobalGrouping)
它是指全部流都发送到Bolt的同一个任务中,再具体一点就是发送给ID最小的任务。
代码:public T globalGrouping(String componentId);
public T globalGrouping(String componentId,String streamId);
5.无分组(NoneGrouping)
如果你不关心流是如何分组的,则可以选择这种分组方式。这种分组方式和随机分组有一种不同之处在于Storm会把这个Bolt放到Bolt的订阅者的同一个线程中执行。
代码:public T noneGrouping(String componentId);
public T noneGrouping(String componentId,String streamId);
6.直接分组(Direct Grouping)
它是一种特殊的分组。这种方式的流分组意味着由元组的生产者决定元组的消费者的接收元组的任务。直接分组只能在已经声明为直接流的流中使用,并且元组必须使用emitDirect方法来发射。
代码:public T directGrouping(String componentId);
public T directGrouping(String componentId,String streamId);
7.本地或者随机分组(LocalOrshuffleGrouping)
如果目标Bolt在同一个工作进程存在一个或多个任务,元组会随机分配给这些任务,否则,该分组方式与随机分组方法是一样的。
代码:public T localOrshuffleGrouping(String componentId);
public T localOrshuffleGrouping(String componentId,String streamId);