在kafka中创建主题的最佳途径是什么?
在新的生产者API中,当我尝试将消息发布到非现有主题时,它首次失败然后成功发布。
答案 0 :(得分:28)
当您启动Kafka代理时,您可以在conf/server.properties
文件中定义一组属性。此文件只是键值属性文件。其中一个属性是auto.create.topics.enable
,如果它设置为true(默认情况下),当您向不存在的主题发送消息时,Kafka将自动创建主题。
您可以找到的所有配置选项都已定义here。恕我直言,创建主题的简单规则如下:副本的数量必须不小于您拥有的节点数。主题数必须是群集中节点数的乘数,例如:
答案 1 :(得分:15)
分区编号确定主题的并行性,因为一个分区只能由使用者组中的一个使用者使用。例如,如果一个主题只有10个分区,而消费者组中只有20个消费者,则10个消费者处于空闲状态,没有收到任何消息。这个数字真的取决于你的申请,但1-1000s都是合理的。
副本号由您的耐久性要求决定。对于具有复制因子N的主题,Kafka可以容忍最多N-1个服务器故障,而不会丢失任何提交给日志的消息。 3个副本是常见配置。当然,副本号必须小于或等于您的经纪人号码。
当Kafka在服务器上自动创建主题时,auto.create.topics.enable 属性控制。如果将此设置为true,则当应用程序尝试生成,使用或获取不存在的主题的元数据时,Kafka将自动使用默认复制因子和分区数创建主题。我建议在生产中关闭它并提前创建主题。
答案 2 :(得分:2)
我想分享我最近在博客The Side Effect of Fetching Kafka Topic Metadata中描述的经验,并针对在此提出的某些问题给出答案。
1)什么是建立在卡夫卡主题的最佳方式是什么?在发布消息之前,我们需要创建主题吗?
我认为,如果我们知道我们将预先使用固定名称的Kafka主题,那么最好在创建或读取主题之前先创建该主题。通常可以使用bin / kafka-topics.sh在启动后脚本中完成此操作,例如,请参见official documentation。或者我们可以使用在Kafka 0.11.0.0中引入的KafkaAdminClient。
另一方面,我确实看到某些情况下需要动态生成主题名称。在这些情况下,我们将无法知道固定的主题名称,而只能依靠“ auto.create.topics.enable”属性。启用后,将自动创建一个主题。这引出了第二个问题:
2)当auto.create.topics.enable为true时,哪些操作会导致创建
实际上就像@Lan已经指出
如果将其设置为true,则当应用程序尝试产生,使用, 或获取不存在的主题的元数据,Kafka会自动 使用默认的复制因子和数量创建主题 分区。
我想更简单地说:
如果为Kafka经纪人启用了自动主题创建,则只要Kafka经纪人看到特定的主题名称,就会创建该主题(如果该主题尚不存在)
获取元数据会自动创建主题的事实经常被包括我在内的人们所忽略。一个特定的示例是使用consumer.partitionFor(topic)API,如果给定主题不存在,则此方法将创建给定主题。
对于我对上面提到的更多细节感兴趣的任何人,您也可以The Side Effect of Fetching Kafka Topic Metadata来浏览我自己的博客文章。
答案 3 :(得分:1)
设置属性
auto.create.topics.enable=true
在您的server.properties文件中,如果您有多个代理,则对所有服务器* .properties文件执行相同操作,然后重新启动kafka-server。
但请确保在服务器* .properties num.partitions=int
中为相应的数字设置分区,否则如果稍后增加分区将会出现性能问题。
答案 4 :(得分:1)
Kafka的基本并行度是分区。在生产者和代理方面,对不同分区的写入可以完全并行完成。
要记住的事情
根据经验,将每个代理的分区数限制为100 x b x r
可能是个好主意,
其中b
是代理的数量,r
是复制因子。
例如: 如果群集中有9个代理/节点,则主题可以是
编辑:有关详细信息,请参阅文章How to choose the number of topics/partitions in a Kafka cluster?(已从中获取答案)
答案 5 :(得分:0)
您可以通过编程方式创建主题。
public class CreateTopic {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Properties config = new Properties();
config.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
AdminClient admin = AdminClient.create(config);
//creating new topic
System.out.println("-- creating --");
NewTopic newTopic = new NewTopic("my-new-topic", 1, (short) 1);
admin.createTopics(Collections.singleton(newTopic));
//listing
System.out.println("-- listing --");
admin.listTopics().names().get().forEach(System.out::println);
}
}