【问题标题】:What atomicity guarantees - if any - does Kafka have regarding batch writes?Kafka 对批量写入有哪些原子性保证(如果有的话)?
【发布时间】:2019-12-08 09:24:45
【问题描述】:

我们现在正在将一项服务从通过传统通信技术推送数据转移到 Apache Kafka。
当前的逻辑是向 IBM MQ 发送消息并在发生错误时重试。我想重复一遍,但我不知道经纪人在那种情况下提供什么保证。
假设我通过 Java 客户端库通过生产者批量发送 100 条消息。假设它到达集群,是否有可能只接受它的一部分(例如,磁盘已满,或者我在写入时触及的某些分区复制不足)?我可以从我的生产者那里检测到该问题并仅重试那些未被接受的消息吗?
我搜索了kafka atomicity guarantee,但没有找到,可能有一个众所周知的术语

【问题讨论】:

    标签: apache-kafka atomic


    【解决方案1】:

    当你说你批量发送 100 条消息时,你的意思是,你想控制这个消息的数量,或者可以让生产者批量发送一定数量的消息,然后批量发送?

    由于不确定您是否可以控制一个生产者批次中生成的消息数量,API 会将它们排队并为您批处理,但不能保证将它们全部一起批处理(不过我会检查一下)。

    如果您可以让 API 为您批处理一定数量的消息,这里有一些关于如何确认消息的线索。

    在与生产者打交道时,Kafka 在写入(也称为“批量写入”)方面具有某种可靠性

    正如此幻灯片分享帖子中所述: https://www.slideshare.net/miguno/apache-kafka-08-basic-training-verisign (83)

    The original list of messages is partitioned (randomly if the default partitioner is used) based on their destination partitions/topics, i.e. split into smaller batches. 
    Each post-split batch is sent to the respective leader broker/ISR (the individual send()’s happen sequentially), and each is acked by its respective leader broker according to request.required.acks
    

    所以关于原子性.. 对于上述行为,不确定整个批次是否会被视为原子性。也许您可以确保为每条消息使用相同的密钥发送您的一批消息,因为它们将进入同一个分区,因此可能成为原子

    如果您在制作时需要更清楚地了解确认规则,请看这里是如何工作的 如这里所述https://docs.confluent.io/current/clients/producer.html

    You can control the durability of messages written to Kafka through the acks setting. 
    The default value of "1" requires an explicit acknowledgement from the partition leader that the write succeeded. 
    The strongest guarantee that Kafka provides is with "acks=all", which guarantees that not only did the partition leader accept the write, but it was successfully replicated to all of the in-sync replicas.
    

    如果您的目标是在生产时没有重复,您还可以查看 producer enable.idempotence 行为。

    亚尼克

    【讨论】:

    • 我同意客户为我做批处理(我知道内部队列) - 抱歉,我的问题不清楚。我无法为批处理中的所有消息指定相同的键,因为我需要基于其他字段进行分区
    • 因此,如果客户端发送队列已满,它会向每个分区叶节点发送 3 个微批处理,其中一个已确认 - 我想由客户端决定是否抛出异常还是不行?
    • 是的,客户端您可以对 KafkaProducer.send() 调用(异步)的未来结果执行 get(),并且在元数据中,如果我是正确的,您应该有类似每个分区的结果。 (Map[TopicPartition, LogAppendResult] 根据 ReplicaManager 类代码)。在未来,您将拥有元数据和异常(如果发生错误),您可以检查此异常并做任何您认为有用的事情。
    • 还有另一种选择 - 使用 idempotent producer。它有一些限制,主要是acks=all 设置是必须的,这意味着如果您的至少一个经纪人出现故障,生产者将停止
    猜你喜欢
    • 1970-01-01
    • 2013-10-01
    • 2010-10-20
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多