Kafka Streams-KTable的

时间:2018-09-19 09:43:52

标签: apache-kafka apache-kafka-streams

问题背景

当前,我们正在使用:Kafka Streams API(版本1.1.0)来处理来自Kafka集群的消息(3个代理,每个主题3个分区,复制因子2)。已安装的Kafka版本为1.1.1。

最终用户向我们报告了数据消失的问题。他们报告说突然他们看不到任何数据(例如,昨天他们可以在UI中看到n条记录,第二天早上的表是空的)。我们检查了这个特定用户的变更日志主题,它看起来很奇怪,看起来几天不活动之后(给定的键值对可能连续几天都没有变化),缺少变更日志主题中的总价值。

代码

KTable组装线:(消息由事件中的“用户名”分组)


@Bean
public KTable<UsernameVO, UserItems> itemsOfTheUser() {
    return streamsBuilder.stream("application-user-UserItems", Consumed.with(Serdes.String(), serdes.forA(UserItems.class)))
                         .groupBy((key, event) -> event.getUsername(),
                                 Serialized.with(serdes.forA(UsernameVO.class), serdes.forA(UserItems.class)))
                         .aggregate(
                                 UserItems::none,
                                 (key, event, userItems) ->
                                         userItems.after(event),
                                 Materialized
                                         .<UsernameVO, UserItems> as(persistentKeyValueStore("application-user-UserItems"))
                                         .withKeySerde(serdes.forA(UsernameVO.class))
                                         .withValueSerde(serdes.forA(UserItems.class)));
}

汇总对象(KTable值):


public class UserItems {

private final Map<String, Item> items;

public static UserItems none() {
    return new UserItems();
}

private UserItems() {
    this(emptyMap());
}

@JsonCreator
private UserItems(Map<String, Item> userItems) {
    this.userItems = userItems;
}

@JsonValue
@SuppressWarnings("unused")
Map<String, Item> getUserItems() {
    return Collections.unmodifiableMap(items);
}

...
public UserItems after(ItemAddedEvent itemEvent) {
    Item item = Item.from(itemEvent);

    Map<String, Item> newItems = new HashMap<>(items);
    newItems.put(itemEvent.getItemName(), item);
    return new UserItems(newItems);
}

Kafka主题

application-user-UserItems


此源主题没有问题。保留设置为最大,所有消息始终显示。


application-user-UserItems-store-changelog (紧凑型,具有默认配置-保留期未更改,也没有任何更改)


这是奇怪的部分。我们可以在变更日志中观察到某些用户的值正在丢失:

Offset | Partition |   Key   |  Value  
...........................................  
...  
320         0        "User1" : {"ItemName1":{"param":"foo"}}  
325         0        "User1" : {"ItemName1":{"param":"foo"},"ItemName2":{"param":"bar"}}  
1056        0        "User1" : {"ItemName3":{"param":"zyx"}}  
...    

我们可以从上面看到,首先,消息被正确聚合:处理了Item1,然后将Item2应用于聚合。但是经过一段时间(可能是几天)后,正在处理另一个事件-似乎缺少“ User1”键下的值,并且仅存在Item3。

在该应用程序中,用户无法一次删除所有项并添加另一项-用户只能逐项添加或删除项。因此,如果他删除ItemName1和ItemName2,然后添加ItemName3,我们将在更改日志中期望类似的内容

Offset | Partition |   Key   |  Value   
..............................................  
...  
320         0        "User1" : {"ItemName1":{"param":"foo"}}   
325         0        "User1" : {"ItemName1":{"param":"foo"},"ItemName2":{"param":"bar"}}   
1054        0        "User1" : {"ItemName2":{"param":"bar"}}   
1055        0        "User1" : {}   
1056        0        "User1" : {"ItemName3":{"param":"zyx"}}  

结论

起初,我们认为它与changelog主题保留有关(但我们对其进行了检查,并且仅启用了压缩)。

application-user-UserItems-store-changelog  PartitionCount:3    ReplicationFactor:1 Configs:cleanup.policy=compact,max.message.bytes=104857600   
    Topic: application-user-UserItems-store-changelog   Partition: 0    Leader: 0   Replicas: 0 Isr: 0   
    Topic: application-user-UserItems-store-changelog   Partition: 1    Leader: 2   Replicas: 2 Isr: 2   
    Topic: application-user-UserItems-store-changelog   Partition: 2    Leader: 1   Replicas: 1 Isr: 

任何想法或提示将不胜感激。干杯

1 个答案:

答案 0 :(得分:0)

我遇到了与您描述的问题相同的问题,似乎该问题与您的kafka-streams配置有关。 您已经提到“源”主题具有以下配置:

3个代理,每个主题3个分区,复制因子2

确保将以下属性至少设置为2(默认设置为1)到kafka流配置(replication.factor)

StreamsConfig.REPLICATION_FACTOR_CONFIG [replication.factor]

这也与您编写的内容相对应(changelog主题的复制因子设置为1)

application-user-UserItems-store-changelog PartitionCount:3 ReplicationFactor:1 Configs:cleanup.policy = compact,max.message.bytes = 104857600

因此,我的假设是由于代理中断而丢失了数据(由于复制因子2,数据应保留在源主题中,因此您可以重新处理并填充变更日志主题)