【问题标题】:Can I use the same state.dir for multiple instances in Kafka streams?我可以对 Kafka 流中的多个实例使用相同的 state.dir 吗?
【发布时间】:2019-07-03 05:31:16
【问题描述】:

我的用例是获取 Kafka 主题中 any 键的最新值。为此,我目前正在使用 GlobalStateStore。

问题是,如果每个实例都有不同的application.id,则会创建不同的状态目录。

我想要的是在所有实例中重用现有的状态存储目录以避免重复数据。 这是因为,我所有的应用程序实例都运行在同一台机器上,所以没有不同的状态目录。

我做了以下事情:

使用相同的 application.id 并创建 2 个流实例, 2 个实例指向同一个 state.dir 但状态存储实例不同(java 对象不同)statestore1 和 statestore2

然后作为测试,我做了以下事情:

while(true)
{
 new Thread(()-> stateStore1.get(key)).start();
 new Thread(()-> stateStore2.get(key)).start();
}

然后我开始在主题中产生价值......

我观察到所有状态存储实例(statestore1 和 statestore2)都在更新同一个状态存储(即相同 state.dir)(因为那是代码)

我在测试中没有遇到任何问题。但是..我想在将数据写入state.dir之前应该获取一个写锁。 现在,如果由于某种原因 statestore1 没有释放锁,那么 statestore2 会一直等待吗?

我上面的方法是安全还是有其他方法?

更新:

用例是我希望在不同的进程(不同的 JVM 实例)之间共享一些公共数据。由于数据是通用的,因此不需要为每个进程都有一个全局存储(因为它是多余的)。

所有进程都应该能够读取和写入该存储,因为每个进程都是相互独立的。 因此,如果一个进程出现故障,另一个进程可以完成它的工作(将最新值存储在全局存储中并在需要时获取它)。

【问题讨论】:

    标签: apache-kafka apache-kafka-streams


    【解决方案1】:

    如果你在同一台机器上运行所有,并且你想共享一个全局存储,你不应该使用多个实例,而应该在一个实例中使用多个线程。

    全局存储旨在为每个实例复制,而这正是您要避免的。

    【讨论】:

    • 不幸的是,我们有不同的应用程序在不同的 JVM 实例上运行,因此不可能有多线程。如果我禁用缓存并确保仅在值旧时调用put,会发生什么情况。这样,所有人都会看到相同的值,只有一个(第一个)会调用 put?
    • different applications -- 你的意思是同一个应用程序的不同 instance 吗?还是不同的应用程序(即使用不同的application.id)? so it is not possible to have multi-threading there: 为什么?这是您可以设置的配置num.stream.threads。为什么不能运行单个 JVM 而不是多个。 --- 缓存与您的问题无关。
    • 基本上,它们是在同一台机器上的不同 JVM 实例中运行的独立组件(每个都有自己的特定目的),我没有问题给它们所有人提供相同的 application.id,尽管它们在不同的实例(进程)上运行。
    • 用例是它们都共享一个公共信息。由于它们在同一台机器上运行,我想避免为每个进程创建一个全局存储,因为它是冗余的(因为数据相同),而是使用相同的。
    • 好的。所以,你说我可以将 same application.id 用于不同的实例(在同一台机器上运行的不同 JVM 进程)并实现我想要的(即写入和读取)。在这种情况下,由于它们在不同的进程上运行,因此它们具有不同的 KafkaStreams 对象,这些对象具有相同的 application.id
    【解决方案2】:

    首先,state_dir 的参数是目录的参数,其中将创建一个值为application.id 的文件夹。

    例如,如果state_dirC:\tmpapplication.idtest,那么文件夹将为C:\tmp\test

    因此,如果将state_dir 指定为C:\tmp\test 而不是C:\tmp 具有相同的application.id 甚至不同的application.id,则将在C:\tmp\test\ 中创建一个新目录为@987654333 @ 或C:\tmp\test\some_other_application_id

    这些不会相互冲突。仍将有多家全球商店。

    但是,如果 state_dir 对于两个 KafkaStreams 实例都被指定为 C:\tmp,则会出现异常说明

    无法锁定全局状态目录。如果多个 KafkaStreams 实例使用相同的主机在同一主机上运行 状态目录

    对于所有实例有一个共同位置的用例,最好使用数据库作为 Kafka 的接收器(使用 Kafka 连接 API 或手动从流写入数据库)。

    如果用例不需要复杂的类似 SQL 的查询,那么您可以拥有自己的 RocksDB,它将为同一台机器上运行的所有实例写入同一目录。

    Kafka 似乎不支持这种开箱即用的用例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-16
      相关资源
      最近更新 更多