永久 Kafka Streams/KSQL 保留策略

Permanent Kafka Streams/KSQL retention policy

我目前正在处理一个用例,在该用例中跟踪用户与平台的交互,从而生成事件流,这些事件被存储到 kafka 中,随后将在 Kafka 中处理 Streams/KSQL。

但是我 运行 遇到了一个关于状态存储和变更日志主题保留策略的问题。用户会话可能会在时间上无限期地发生,因此我必须保证状态将在此期间保持不变,并在节点和集群范围内发生故障时恢复。在搜索过程中,我们发现了以下信息:


https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Streams+Internal+Data+Management

Kafka Streams allows for stateful stream processing, i.e. operators that have an internal state. (...). The default implementation used by Kafka Streams DSL is a fault-tolerant state store using 1. an internally created and compacted changelog topic (for fault-tolerance) and 2. one (or multiple) RocksDB instances (for cached key-value lookups). Thus, in case of starting/stopping applications and rewinding/reprocessing, this internal data needs to get managed correctly.

(...) Thus, RocksDB memory requirement does not grow infinitely (in contrast to changelog topic). (KAFKA-4015 was fixed in 0.10.1 release, and windowed changelog topics don't grow unbounded as they apply an additional retention time parameter).


"For windowed KTables there is a local retention time and there is the changlog retention time. You can set the local store retention time via Materialized.withRetentionTime(...) -- the default value is 24h.

If a new application is created, changelog topics are created with the same retention time as local store retention time."


https://docs.confluent.io/current/streams/developer-guide/config-streams.html

windowstore.changelog.additional.retention.ms 参数状态:

Added to a windows maintainMs to ensure data is not deleted from the log prematurely. Allows for clock drift.


Kafka Streams 似乎同时维护了一个(复制的)本地状态存储和一个用于容错的变更日志主题,两者都有一个有限的、可配置的保留期,并且一旦保留时间到期就会清除记录。这将导致我们平台中无法接受的数据丢失,从而引发以下问题:

  1. Kafka Streams 是否真的会随着时间的推移清理默认状态存储,还是我误解了什么?是否存在数据丢失的实际风险?

  2. 在那种情况下,是否建议甚至可能为状态存储设置无限保留策略?或者也许可以有另一种方法来确保状态将被持久化,例如使用更传统的数据库作为状态存储,如果这有意义的话?

  3. 保留策略是否适用于备用副本?

  4. 如果无法永久持久化状态,是否有其他流处理框架更适合我们的用例?

如有任何澄清,我们将不胜感激。

您似乎在问两件不同的事情。会话 windows 和更新日志主题...

压缩主题保留唯一密钥对永远。会话 window 持续时间可能应该随着时间的推移而关闭;今天的一个用户会话 week/month/year 可以说是一个新会话,您应该将每个单独的会话 window 作为用户 ID 的 集合 绑定在一起,而不仅仅是存储最近的会话(这意味着从状态存储中删除以前的会话)