如何在使用Spring云流Kinesis时设置PartitionKey

时间:2018-03-13 09:56:44

标签: spring spring-cloud spring-cloud-stream

在我的代码中,我使用了setHeader

mysource.getChannel1()
        .send(MessageBuilder
        .withPayload(new Person("messageA", 1))
        .setHeader("partitionKey", 345).build());

在我添加的属性文件中:

spring.cloud.stream.bindings.channel1.producer.partitionKeyExpression = 
                                                      headers['partitionKey']

但仍然,PartitionKey不是345 partitionKey是一些哈希值2133325211。 即使我使用相同的partitionKey标头插入2条消息,在Kinesis中我们也会获得2个不同的分区键。

当我尝试

spring.cloud.stream.bindings.output.producer.partitionKeyExpression = payload.id

partitionKey始终等于partitionKey-0

我的问题:

如何将分区键设置为特定值?

1 个答案:

答案 0 :(得分:1)

当前实现依赖于SCST中针对BinderHeaders.PARTITION_HEADER的内置算法的问题,partition number生成payload.id,这与Kinesis性质不符合我们应该如何选择特别是碎片。好吧,实际上我们根本没有选择它。我们提供一些分区键值,让消息通过该值的哈希在同一个分片中结算。或者我们可以提供显式哈希以确保我们转到相同的分片。基本上它最终是相同的 - 我们最终通过哈希结束了分片。

为了使其适用于您的BinderHeaders.PARTITION_OVERRIDE用例,我建议您查看@Bean @GlobalChannelInterceptor(order = Integer.MIN_VALUE, patterns = Source.OUTPUT) public ChannelInterceptor partitionOverrideInterceptor(BindingProperties bindingProperties, StandardEvaluationContext evaluationContext) { return new ChannelInterceptorAdapter() { @Override public Message<?> preSend(Message<?> message, MessageChannel channel) { return MessageBuilder.fromMessage(message) .setHeader(BinderHeaders.PARTITION_HEADER, bindingProperties.getProducer() .getPartitionKeyExpression() .getValue(evaluationContext, message)) .build(); } }; } 标题方法:

scst_partition

这样,partitionKeyExpression标题将具有您希望通过KinesisMessageHandler提供的确切值,PutRecordRequest将在SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'main1: LOOP SELECT @z := operation_id FROM operations_test WHERE operation_id' at line 2 中具有适当的目标哈希值。

有关详细信息,请参阅https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis/issues/52