Java Apache Storm一次性处理

Java Apache Storm一次性处理,java,amazon-redshift,apache-storm,trident,Java,Amazon Redshift,Apache Storm,Trident,我们目前正在集群拓扑模式下使用ApacheStorm 0.9.5来处理Amazon运动记录(spout),并将其存储到红移数据仓库(bolt)中。我们的风暴集群部署在AWS中,由1个nimbus+UI节点、1个zookeeper节点和3个supervisor+logviewer节点组成。我们的拓扑配置支持处理多个Kinesis流,每个流包括: 一个动觉流喷口,用于监听传入的记录 一个红移螺栓,用于将记录插入数据仓库 拓扑结构: final TopologyBuilder topologyBu

我们目前正在集群拓扑模式下使用ApacheStorm 0.9.5来处理Amazon运动记录(spout),并将其存储到红移数据仓库(bolt)中。我们的风暴集群部署在AWS中,由1个nimbus+UI节点、1个zookeeper节点和3个supervisor+logviewer节点组成。我们的拓扑配置支持处理多个Kinesis流,每个流包括:

  • 一个动觉流喷口,用于监听传入的记录
  • 一个红移螺栓,用于将记录插入数据仓库
拓扑结构:

final TopologyBuilder topologyBuilder = new TopologyBuilder();

// for every configured kinesis stream
final List<KinesisStreamSpout> kinesisStreamSpouts = kinesisStreamService.getKinesisStreamSpouts();
for (final KinesisStreamSpout kinesisStreamSpout : kinesisStreamSpouts) {
    final String spoutId = kinesisStreamSpout.getSpoutId();
    topologyBuilder.setSpout(spoutId, kinesisStreamSpout.getKinesisSpout());

    // set the corresponding redshift bolt
    final String streamName = kinesisStreamSpout.getStreamName();
    final RedshiftBolt redshiftBolt = new RedshiftBolt(streamName);
    topologyBuilder.setBolt(redshiftBolt.getId(),
        redshiftBolt, stormProperties.getNumberOfWorkersPerStream()).shuffleGrouping(spoutId);
}

return topologyBuilder.createTopology();
final TopologyBuilder TopologyBuilder=新TopologyBuilder();
//对于每个配置的运动流
最终列表kinesisStreamSpouts=kinesisStreamService.getKinesisStreamSpouts();
对于(最终动画片动画片动画片动画片:动画片动画片动画片){
最后一个字符串spaytid=kinesisStreamSpout.getspaytid();
topologyBuilder.setSpout(spoutId,kinesisStreamSpout.getKinesisSpout());
//设置相应的红移螺栓
最后一个字符串streamName=kinesisStreamSpout.getStreamName();
最终RedshiftBolt RedshiftBolt=新RedshiftBolt(streamName);
topologyBuilder.setBolt(redshiftBolt.getId(),
redshiftBolt,stormProperties.getNumberOfWorkersPerStream()).shuffleGrouping(spoutId);
}
返回topologyBuilder.createTopology();
该系统的一个缺陷是无法保证只对输入消息进行一次处理,从而导致多个记录将相同的业务密钥插入目标数据库。为了了解问题的严重程度,我们运行了一个受控测试,发现大约三分之一的输入记录被提交多次处理

根据(目前尚未回答),我们也考虑过使用Trident以保证只处理一次,但也得出结论,在系统中内置幂等性(以及至少一次语义)比增加复杂性更重要,性能降低,并按此建议生成状态


我们现在正在寻求以支持集群的方式在现有拓扑中实现幂等性的最佳方法的建议。到目前为止,我们倾向于引入一种RedisBolt,它将通过元组消息id为值设置关键值。是否存在使用Apache Storm实现这一点的现有模式?

如果您不想使用Trident,您可能需要阅读以下关于“事务拓扑”的文章。这是三叉戟背后的概念,您仍然可以“手动”应用它。对于您的用例来说,这似乎是一个很好的模式:


此外,我还想补充一点,即Storm(与任何其他系统一样,如Apache Flink[免责声明:我是Flink的提交者]和Apache Spark Streaming)只能保证在系统内进行一次处理。如果数据被转发到外部系统,则只有当且仅当外部系统能够支持幂等运算时,才能实现一次完全转发。

如果您不想使用Trident,您可能需要阅读以下关于“事务拓扑”的文章。这是三叉戟背后的概念,您仍然可以“手动”应用它。对于您的用例来说,这似乎是一个很好的模式:


此外,我还想补充一点,即Storm(与任何其他系统一样,如Apache Flink[免责声明:我是Flink的提交者]和Apache Spark Streaming)只能保证在系统内进行一次处理。如果数据被转发到外部系统,则只有当且仅当外部系统能够支持幂等运算时,才能实现一次准确的转发。

您确定在Kinesis中没有重复项吗?1/3的值在我看来非常高…重复提交分析基于Amazon Kinesis Spoute组件从ShardId:SequenceNumber值构造的唯一messageId。换句话说,系统会为同一业务负载的多个Kinesis记录分配一个不同的元组messageId。。。您有许多失败的元组吗?我们的tes运行中没有任何失败的元组。。然而,我们得到的是对同一条消息的重试(使用Kinesis记录序列号锚定):`c.a.s.k.s.s.z.InflightRecordTracker[INFO]使用分区键1序列号495549399127891355254681946468305001458404776150876162重试记录。重试尝试1`您可以发布storm UI的图像->显示可视化(它应该显示拓扑图)。您确定在Kinesis中没有重复的吗?1/3的值在我看来非常高…重复提交分析基于Amazon Kinesis Spoute组件从ShardId:SequenceNumber值构造的唯一messageId。换句话说,系统会为同一业务负载的多个Kinesis记录分配一个不同的元组messageId。。。您有许多失败的元组吗?我们的tes运行中没有任何失败的元组。。然而,我们得到的是对同一条消息的重试(使用Kinesis记录序列号锚定):`c.a.s.k.s.s.z.InflightRecordTracker[INFO]使用分区键1序列号495549399127891355254681946468305001458404776150876162重试记录。重试尝试1`能否发布storm UI的图像->显示可视化(它应显示拓扑图)。