如何通过Java在Kafka中创建主题

如何通过Java在Kafka中创建主题,java,apache-zookeeper,apache-kafka,Java,Apache Zookeeper,Apache Kafka,我想通过java在Kafka(Kafka_2.8.0-0.8.1.1)中创建一个主题。若我在命令提示符下创建一个主题,并且通过JavaAPI推送消息,那个么它就可以正常工作。但是我想通过JavaAPI创建一个主题。经过长时间的搜索,我找到了下面的代码 ZkClient zkClient = new ZkClient("localhost:2181", 10000, 10000); AdminUtils.createTopic(zkClient, myTopic, 10, 1, new Prope

我想通过java在Kafka(Kafka_2.8.0-0.8.1.1)中创建一个主题。若我在命令提示符下创建一个主题,并且通过JavaAPI推送消息,那个么它就可以正常工作。但是我想通过JavaAPI创建一个主题。经过长时间的搜索,我找到了下面的代码

ZkClient zkClient = new ZkClient("localhost:2181", 10000, 10000);
AdminUtils.createTopic(zkClient, myTopic, 10, 1, new Properties());
我尝试了上面的代码,它显示主题已创建,但我无法在主题中推送消息。我的代码有什么错误吗?或者以任何其他方式实现上述目标

编辑-新版卡夫卡不需要Zookeeper。请参阅API版本0.11.0的答复+



原始答案 我把它修好了。。经过长时间的研究

ZkClient zkClient = new ZkClient("localhost:2181", 10000, 10000);
AdminUtils.createTopic(zkClient, myTopic, 10, 1, new Properties());
从上面的代码中,ZkClient将创建一个主题,但该主题信息将不会对卡夫卡产生感知。所以我们要做的是,我们需要按照以下方式为ZkClient创建对象

ZkClient zkClient = new ZkClient("localhost:2181", 10000, 10000, ZKStringSerializer$.MODULE$);
AdminUtils.createTopic(zkClient, myTopic, 10, 1, new Properties());
首先导入下面的语句

import kafka.utils.ZKStringSerializer$;
并按以下方式为ZkClient创建对象

ZkClient zkClient = new ZkClient("localhost:2181", 10000, 10000, ZKStringSerializer$.MODULE$);
AdminUtils.createTopic(zkClient, myTopic, 10, 1, new Properties());

编辑1:(针对@ajkret评论) 上述代码不适用于kafka>0.9,因为api已更改, 对于kafka>0.9,请使用以下代码



只是一个指向任何使用卡夫卡更新版本查看此内容的人的指针(在撰写本文时,我使用的是卡夫卡v0.10.0.0)

你必须改变

AdminUtils.createTopic(zkUtils, topicName, noOfPartitions, noOfReplications, topicConfiguration);
对下列各项:

AdminUtils.createTopic(zkUtils, topicName, noOfPartitions, noOfReplications, true, Enforced$.MODULE$);
完成后关闭连接也是一个好主意

zkClient.close();

对于那些试图在kafka v0.10.2.1中实现这一点并遇到序列化错误“
java.io.streamcorruptedeException:invalid stream header:3139322E
”问题的用户,以下是一个示例工作代码,其中包含所需的导入

import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.PartitionInfo;

import kafka.admin.AdminUtils;
import kafka.admin.RackAwareMode;
import kafka.utils.ZKStringSerializer;
import kafka.utils.ZkUtils;

public static void createTopic(String topicName, int numPartitions, int numReplication) {
        ZkClient zkClient = null;
        ZkUtils zkUtils = null;
        try {
            String zookeeperHosts = "199.98.916.902:2181"; // If multiple zookeeper then -> String zookeeperHosts = "192.168.20.1:2181,192.168.20.2:2181";
            int sessionTimeOutInMs = 15 * 1000; // 15 secs
            int connectionTimeOutInMs = 10 * 1000; // 10 secs

            zkClient = new ZkClient(zookeeperHosts, sessionTimeOutInMs, connectionTimeOutInMs);
            //Ref: https://gist.github.com/jjkoshy/3842975
            zkClient.setZkSerializer(new ZkSerializer() {
                @Override
                public byte[] serialize(Object o) throws ZkMarshallingError {
                    return ZKStringSerializer.serialize(o);
                }

                @Override
                public Object deserialize(byte[] bytes) throws ZkMarshallingError {
                    return ZKStringSerializer.deserialize(bytes);
                }
            });

            zkUtils = new ZkUtils(zkClient, new ZkConnection(zookeeperHosts), false);

            int noOfPartitions = 2;
            int noOfReplication = 3;
            Properties topicConfiguration = new Properties();

            AdminUtils.createTopic(zkUtils, topicName, noOfPartitions, noOfReplication, topicConfiguration,
                    RackAwareMode.Enforced$.MODULE$);

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (zkClient != null) {
                zkClient.close();
            }
        }
    }

AdminUtils API已被弃用。我们可以使用新的API AdminZkClient来管理Kafka服务器中的主题

String zookeeperHost = "127.0.0.1:2181";
Boolean isSucre = false;
int sessionTimeoutMs = 200000;
int connectionTimeoutMs = 15000;
int maxInFlightRequests = 10;
Time time = Time.SYSTEM;
String metricGroup = "myGroup";
String metricType = "myType";
KafkaZkClient zkClient = KafkaZkClient.apply(zookeeperHost,isSucre,sessionTimeoutMs,
                connectionTimeoutMs,maxInFlightRequests,time,metricGroup,metricType);

AdminZkClient adminZkClient = new AdminZkClient(zkClient);

String topicName1 = "myTopic";
int partitions = 3;
int replication = 1;
Properties topicConfig = new Properties();

adminZkClient.createTopic(topicName1,partitions,replication,
            topicConfig,RackAwareMode.Disabled$.MODULE$);

您可以参考此链接了解详细信息:

在API 0.11.0+中,该过程似乎简化了很多。使用该方法,可以按如下方式进行

import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.CreateTopicsResult;
import org.apache.kafka.clients.admin.NewTopic;

Properties properties = new Properties();
properties.load(new FileReader(new File("kafka.properties")));

AdminClient adminClient = AdminClient.create(properties);
NewTopic newTopic = new NewTopic("topicName", 1, (short)1); //new NewTopic(topicName, numPartitions, replicationFactor)

List<NewTopic> newTopics = new ArrayList<NewTopic>();
newTopics.add(newTopic);

adminClient.createTopics(newTopics);
adminClient.close();
bootstrap.servers=localhost:9092
group.id=test
enable.auto.commit=true
auto.commit.interval.ms=1000
key.deserializer=org.apache.kafka.common.serialization.StringDeserializer
value.deserializer=org.apache.kafka.common.serialization.StringDeserializer

请注意,必须关闭AdminClient实例才能反映新创建的主题。

是的,可以向主题发送消息,但消费者无法获取消息?有什么想法吗?你是想让低层次的消费者消费还是高层次的消费者消费?你能提供一些代码吗?在0.9.0.1之后,界面完全改变了。createTopic不再接受ZkClient。AdminUtils与AdminZkClientzkUtils一起被弃用。Kafka 2.12-2.1.0中现在不推荐使用AdminZkClient。类的文档
AdminZkClient
->
这是一个内部类,不提供兼容性保证,有关公开支持的API,请参见org.apache.kafka.clients.admin.AdminClient
,现在的正确答案可在中找到,感谢您的澄清。这是在哪里记录的?不认为它一定需要关闭,基本上,
createTopics
似乎是一个懒惰的方法,返回一个未来类型的对象-要强制执行,您可以尝试从中“获取”响应