我有一个包含客户记录的Kafka主题,称为“客户创建”。每个客户都是该主题中的新记录。有四个分区。
我有两个基于docker镜像confluentinc/cp-ksql-server:5.3.0
运行的ksql-server实例。两者都使用相同的KSQL Service Id。
我已经创建了一个表格:
CREATE TABLE t_customer (id VARCHAR,
firstname VARCHAR,
lastname VARCHAR)
WITH (KAFKA_TOPIC = 'customer-created',
VALUE_FORMAT='JSON',
KEY = 'id');
我是KSQL的新手,但我的理解是KSQL建立在Kafka Streams之上,每个ksql-server实例大致等效于Kafka Streams应用程序实例。我注意到的第一件事是,一旦我启动了ksql-server的新实例,即使它是开发人员模式下的交互式实例,它也已经知道在第一个实例上创建的表/流。其次,我可以从两个实例中基于其ID选择相同的客户,但是我希望只能从一个实例中做到这一点,因为我假定KSQL表与KTable等效,即它仅应包含本地数据,即来自ksql-server实例正在处理的分区的数据。
SET 'auto.offset.reset'='earliest';
select * from t_customer where id = '7e1a141b-b8a6-4f4a-b368-45da2a9e92a1';
无论我将ksql-cli附加到哪个ksql-server实例,我都将得到结果。使用纯Kafka Streams时,使它起作用的唯一方法是使用全局KTable。我从两个实例中得到结果的事实使我有些惊讶,因为according to the docs,“ 只有Kafka Streams DSL具有GlobalKTable的概念”,所以我期望这两个实例中只有一个实例来找到客户。我在任何地方都找不到任何文档来说明如何指定KSQL表应该是本地表还是全局表。
所以这是我的问题:是KSQL Table等同于 global KTable,并且文档具有误导性,还是我连接到的ksql-server实例在以下情况下发出远程请求引擎盖,到负责ID的实例(大概基于分区),如here, for Kafka Streams所述?
答案 0 :(得分:4)
KSQL不支持GlobalKTables
atm。
您在KSQL服务器和Kafka Streams程序之间的类比并不是100%准确。每个 query 是一个Kafka Streams程序(请注意,“程序”可以具有多个 instances )。此外,持久查询和瞬时查询之间也存在差异。从主题创建表时,命令本身仅是元数据操作(与从主题创建CREATE STREAM相似)。对于这两者,都不会执行查询,也不会启动Kafka Streams程序。
有关所有创建的STREAMS和TABLES的信息存储在Kafka集群的共享“命令主题”中。具有相同ID的所有服务器都会收到有关创建的流,表的相同信息。
在CLI中运行的查询是瞬时查询,它们将由单个服务器执行。有关此类瞬时查询的信息不分发给其他服务器。基本上,将生成唯一的查询ID(即application.id
),并且服务器运行单个实例KafakStreams
程序。因此,服务器/程序将预订所有分区。
持久查询(即CREATE STREAM AS
或CREATE TABLE AS
)是查询STREAM或TABLE并生成STREAM或TABLE作为输出的查询。通过“命令主题”将有关持久查询的信息分发给所有服务器(但是,并非所有服务器都将执行所有持久查询-这取决于配置的并行度,将执行多少并行查询)。对于持久查询,每个参与执行查询的服务器都会创建一个运行同一程序的KafkaStreams
实例,并且所有实例都将使用相同的查询ID(即application.id
),因此不同的服务器将订阅不同的主题。