[英]Kafka Streams - disappearing values from KTable's
目前我們正在使用: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);
}
應用程序用戶用戶項
這個源碼題目沒有問題。 它已將保留設置為最大值,所有消息始終存在。
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"}}
起初我們認為它與更改日志主題保留有關(但我們檢查了它並且它只啟用了壓縮)。
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:
任何想法或提示將不勝感激。 干杯
我遇到了與您描述的相同的問題,看來問題與您的 kafka-streams 配置有關。 您已經提到您的“源”主題具有以下配置:
3 個代理,每個主題 3 個分區,復制因子為 2
確保將以下屬性放入 kafka 流配置(replication.factor)至少為 2(默認設置為 1)
StreamsConfig.REPLICATION_FACTOR_CONFIG [replication.factor]
這也對應於您編寫的內容(更改日志主題的復制因子設置為 1)
application-user-UserItems-store-changelog PartitionCount:3 ReplicationFactor:1 Configs:cleanup.policy=compact,max.message.bytes=104857600
因此,我的假設是您因代理中斷而丟失數據(盡管由於復制因子 2,數據應保留在源主題中,因此您可以重新處理和填充更改日志主題)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.