【问题标题】:In-memory vs persistent state stores in Kafka Streams?Kafka Streams中的内存与持久状态存储?
【发布时间】:2023-03-23 07:06:02
【问题描述】:
我已经阅读了有状态流处理overview,如果我理解正确的话,RocksDB 被用作键值存储的默认实现的主要原因之一是一个事实,它与内存中的集合不同,它可以处理大于可用内存的数据,因为它可以刷新到磁盘。这两种类型的存储都可以在应用程序重启后继续存在,因为数据是作为 Kafka 主题备份的。
但是还有其他区别吗?例如,我注意到我的持久状态存储为每个主题分区创建了一些 .log 文件,但它们都是空的。
简而言之,我想知道用内存中的存储替换持久存储的性能优势和可能的风险是什么。
【问题讨论】:
标签:
apache-kafka
apache-kafka-streams
rocksdb
【解决方案1】:
我对 Kafka Streams 的内部结构以及状态存储的不同用例的了解非常有限,尤其是。内存中与持久性,但到目前为止我设法了解到持久性状态存储是为StreamTask 存储在磁盘上(因此名称为persistent)的状态存储。
这并没有给出太多,因为名称本身 in-memory 与 persistent 可能给出了相同的理解,但我发现一些东西非常令人耳目一新 em> 是当我了解到 Kafka Streams 尝试将分区分配给之前分配了分区的相同 Kafka Streams 实例(重新启动或崩溃)。
也就是说,每次重新启动时都会简单地重新创建(重放)内存中的状态存储,这在 Kafka Streams 应用程序启动并运行之前需要一些时间,而持久状态存储已经存在 在磁盘上实现,而 Kafka Streams 实例唯一需要重新创建状态存储的就是从磁盘加载文件(而不是从需要更长时间的变更日志主题)。
我希望这会有所帮助,如果我错了(或部分正确),我会很高兴得到纠正。
【解决方案2】:
我认为没有任何真正的理由来交换当前的 RocksDB 存储。实际上 RocksDB 是最快的 k,v 存储之一:
Percona benchmarks (based on RocksDB)
with in-memory ones - RocksDB 已经充当内存中的一些 LRU 算法:
RocksDB architecture
The three basic constructs of RocksDB are memtable, sstfile and logfile. The memtable is an in-memory data structure - new writes are inserted into the memtable and are optionally written to the logfile.
但选择此实现还有一个更明显的原因:
RocksDB source code
如果您查看源代码比率 - 有很多 Java api 从 C++ 代码中暴露出来。因此,使用公开的 api 将该产品集成到现有的 Java - based Kafka 生态系统中并全面控制存储要简单得多。