我在Kafka中有2个主题:MetaData和MasterData。 我正在使用Kafka Listners实时读取数据。有2种情况:
蚂蚁建议如何实现这一目标?
答案 0 :(得分:1)
在评论中澄清之后,这就是我所了解的,您想要实现的目标:
您有一个类似system的数据库,并且来自kafka主题的元数据用于调整表结构。然后,实际数据进入主kafka主题,然后您希望将其插入表中。换句话说:您想使用kafka定义数据的结构。
我不确定,如果这就是我所说的Kafka的常规用例,那是因为它是交换事件(即数据)的接口。您尝试做的是将系统用作定义数据结构的一种方式。但这只是我的意见。
如评论中前面所述,实际上没有办法说一个主题中没有消息。您只能说:还没有消息“还”。您“可能”可以做的是:当master
主题中的消息到达时,您首先检查meta
主题,如果也有消息。如果存在,则应用数据结构中的更改,然后从主主题导入消息。
另一种选择是使用Kafka Streams代替原始使用者
结合两个主题,例如join
。
无论如何定义数据结构,通常都可以使用诸如Avro之类的东西,它可以为您提供模式演变以及更多功能。然后编写您的应用程序以了解架构更改,然后将其相应地应用于数据库表。
更新:如何使用Kafka Streams解决
如上所述,使用Kafka Streams可能是解决您的情况的方法。让我解释一下,我在一些伪kafka流代码中的意思:
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.kstream.GlobalKTable;
import java.nio.charset.StandardCharsets;
/**
* Just an incomplete Kafka Streams Code Demo to show how the problem could
* be solved with this framework instead of using the consumers directly.
* Kafka Streams Boilerplate code not included.
*/
public class Example {
private static final String META_TOPIC = "meta";
private static final String MASTER_TOPIC = "master";
// You have to make sure, the meta data is stored under this
// specific key in the meta topic.
private static final byte[] META_KEY = MetaEvent.class.getName().getBytes(StandardCharsets.UTF_8);
public static void main(String[] args) {
new Example().createTopology();
}
public void createTopology() {
final StreamsBuilder builder = new StreamsBuilder();
final GlobalKTable<byte[], MetaEvent> metaTable = builder.globalTable(META_TOPIC);
builder.<byte[], MasterEvent>stream(MASTER_TOPIC)
.leftJoin(
metaTable,
(k, v) -> META_KEY,
MasterWithMeta::new)
.foreach(this::handleEvent);
}
private void handleEvent(byte[] key, MasterWithMeta masterWithMeta) {
// 1) check if meta has changed, if so, apply changes to database
// 2) import master data to database
}
}
class MasterWithMeta {
private final MasterEvent master;
private final MetaEvent meta;
public MasterEvent getMaster() {
return master;
}
public MetaEvent getMeta() {
return meta;
}
public MasterWithMeta(MasterEvent master, MetaEvent meta) {
this.master = master;
this.meta = meta;
}
public static MasterWithMeta create(MasterEvent master, MetaEvent meta) {
return new MasterWithMeta(master, meta);
}
}
class MetaEvent {
// ...
}
class MasterEvent {
// ...
}