KSQL 是在后台发出远程请求,还是 Table 实际上是一个全局 KTable?

Ant*_*era 1 apache-kafka-streams ksqldb

我有一个包含客户记录的 Kafka 主题,称为“客户创建”。每个客户都是主题中的一个新记录。有4个分区。

我有两个基于 docker image 的 ksql-server 实例正在运行confluentinc/cp-ksql-server:5.3.0。两者都使用相同的KSQL 服务 ID

我创建了一个表:

CREATE TABLE t_customer (id VARCHAR, 
                         firstname VARCHAR, 
                         lastname VARCHAR)
WITH (KAFKA_TOPIC = 'customer-created', 
      VALUE_FORMAT='JSON', 
      KEY = 'id');
Run Code Online (Sandbox Code Playgroud)

我是 KSQL 的新手,但我的理解是 KSQL 构建在 Kafka Streams 之上,并且每个 ksql-server 实例大致相当于一个 Kafka 流应用程序实例。我注意到的第一件事是,一旦我启动 ksql-server 的新实例,它就已经知道在第一个实例上创建的表/流,即使它是开发人员模式下的交互式实例。其次,我可以根据两个实例的 ID 选择同一个客户,但我希望只能从其中一个实例中选择相同的客户,因为我假设 KSQL 表等同于 KTable,即它应该只包含本地数据,即来自 ksql-server 实例正在处理的分区。

SET 'auto.offset.reset'='earliest';
select * from t_customer where id = '7e1a141b-b8a6-4f4a-b368-45da2a9e92a1';
Run Code Online (Sandbox Code Playgroud)

无论我将 ksql-cli 附加到哪个 ksql-server 实例,我都会得到结果。在使用普通的 Kafka Streams 时,我可以让它工作的唯一方法是使用全局 KTable。我从两个实例中得到结果的事实让我有点惊讶,因为根据文档,“只有 Kafka Streams DSL 具有 GlobalKTable 的概念”,所以我预计这两个实例中只有一个可以找到客户。我没有在任何地方找到任何解释如何指定 KSQL 表应该是本地或全局表的文档。

所以这是我的问题:KSQL 表是否等同于全局KTable 并且文档具有误导性,或者是我连接到的 ksql-server 实例,在后台向负责 ID 的实例发出远程请求(大概基于分区),如此处所述,对于 Kafka Streams

Mat*_*Sax 5

KSQL 不支持GlobalKTablesatm。

您在 KSQL 服务器和 Kafka Streams 程序之间的类比并不是 100% 准确。每个查询都是一个 Kafka Streams 程序(注意,一个“程序”可以有多个实例)。此外,持久查询和临时查询之间也存在差异。当您从主题创建 TABLE 时,命令本身只是一个元数据操作(类似于从主题创建流)。两者都没有执行查询,也没有启动 Kafka Streams 程序。

所有创建的 STREAMS 和 TABLES 的信息都存储在 Kafka 集群中的共享“命令主题”中。所有具有相同 ID 的服务器接收有关创建的流、表的相同信息。

在 CLI 中运行的查询是临时查询,它们将由单个服务器执行。有关此类临时查询的信息不会分发到其他服务器。基本上,生成唯一的查询 ID(即application.id)并且服务器运行单个实例KafakStreams程序。因此,服务器/程序将订阅所有分区。

持久查询(即,CREATE STREAM ASCREATE TABLE AS)是查询一个流或表,并产生一个流或表作为输出的查询。有关持久查询的信息通过“命令主题”分发到所有服务器(但是,并非所有服务器都会执行所有持久查询——这取决于配置的并行度将执行多少个)。对于持久查询,参与执行查询的每个服务器都会创建一个KafkaStreams运行相同程序的实例,并且都将使用相同的查询 ID(即application.id),因此不同的服务器将订阅不同的主题。