8.storm中不同的流分组方式

来源:互联网 发布:无人驾驶数据 编辑:程序博客网 时间:2024/06/09 04:13
packagebacktype.storm.topology;
importbacktype.storm.generated.GlobalStreamId;
importbacktype.storm.generated.Grouping;
importbacktype.storm.grouping.CustomStreamGrouping;
importbacktype.storm.tuple.Fields;

publicinterfaceInputDeclarer<T extends InputDeclarer> {
   //字段分组
   publicT fieldsGrouping(String componentId, Fieldsfields);
   public T fieldsGrouping(String componentId, String streamId, Fieldsfields);

          //全局分组
   publicT globalGrouping(String componentId);
   
public T globalGrouping(StringcomponentId, StringstreamId);

    //随机分组
   public T shuffleGrouping(String componentId);
   publicT shuffleGrouping(StringcomponentId, StringstreamId);

        //本地或随机分组
   publicT localOrShuffleGrouping(StringcomponentId);
   
public T localOrShuffleGrouping(StringcomponentId, StringstreamId);

        //无分组
   publicT noneGrouping(String componentId);
   
public T noneGrouping(StringcomponentId, StringstreamId);

        //广播分组
   publicT allGrouping(String componentId);
   
public T allGrouping(StringcomponentId, StringstreamId);

        //直接分组
   publicT directGrouping(String componentId);
   
public T directGrouping(StringcomponentId, StringstreamId);

        //自定义分组
   publicT customGrouping(String componentId, CustomStreamGroupinggrouping);
   
public T customGrouping(StringcomponentId, StringstreamId, CustomStreamGroupinggrouping);
   
   public T grouping(GlobalStreamId id, Grouping grouping);
}

1. 随机分组
随机分组(Shuffle Grouping)是最常用的流分组方式,它随机地分发元组到Bolt 上的任 务,这样能保证每个任务得到相同数量的元组。
随机分组执行原子操作,这是非常有用的,例如数学运算。但是,如果操作不能被随机分发的话,应该考虑使用其他的分组方式,例如,在单词统计(WordCount)例子中,需要计算单词,就不适合使用随机分组。

 2.字段分组
字段分组(Fields Grouping)根据指定字段对流进行分组。例如,如果流是按user-id字段进行分组,具有相同 user-id 的元组总是被分发到相同的任务,具有不同 user-id 的元组可能被分发到不同的任务。
字段分组是实现流连接和关联,以及大量其他的用例的基础。在实现上,字段分组使用取模散列来实现。

3. 广播分组
广播分组(All Grouping)是指流被发送到所有Bolt 的任务中。使用这个分组方式时要小心。

4. 全局分组
全局分组(
Global Grouping)是指全部流都发送到Bolt 的同一个任务中,再具体一点,
是发送给 ID 最小的任务。

5. 无分组
假定你不关心流是如何分组的,则可以使用这种分组方式。目前这种分组和随机分组是一 样的效果,有一点不同的是Storm 会把这个 Bolt 放到 Bolt 的订阅者的同一个线程中执行。

6. 直接分组
直接分组(Direct Grouping)是一种特殊的分组。这种方式的流分组意味着由元组的生产 者决定元组的消费者的接收元组的任务。直接分组只能在已经声明为直接流(Direct Stream) 的流中使用,并且元组必须使用 emitDirect 方法来发射。Bolt通过 TopologyContext 对象或者 OutputCollector 类的 emit 方法的返回值,可以得到其消费者的任务 id 列表(List<Integer>)。

7. 本地或者随机分组
如果目标
Bolt 在同一工作进程存在一个或多个任务,元组会随机分配给这些任务。否则,
该分组方式与随机分组方式是一样的。

8. 自定义分组
可以自定义流分组的方式,通过实现CustomStreamGrouping 接口来创建自定义的流分组。 CustomStreamGrouping接口的定义如下:
public interface CustomStreamGrouping extends Serializable {
void prepare(WorkerTopologyContext context, GlobalStreamId stream, List

<Integer> targetTasks);
List<Integer> chooseTasks(int taskId, List<Object> values);
}
CustomStreamGrouping接口主要有两个方法:prepare chooseTasks
CustomStreamGrouping接口的具体实现,可以参考如下的代码类:
storm.trident.partition.GlobalGrouping
storm.trident.partition.IdentityGrouping
storm.trident.partition.IndexHashGrouping
backtype.storm.testing.NGrouping
builder.setBolt("exclaim2", new ExclamationBolt(), 2).shuffleGrouping("exclaim1");
builder.setBolt("exclaim2", new ExclamationBolt(), 2).customGrouping("exclaim1", newGlobalGrouping());//自定义时的区别!!!

0 0
原创粉丝点击