diff --git a/mq/kafka/kafka.md b/mq/kafka/kafka.md index e305af1..e88de5a 100644 --- a/mq/kafka/kafka.md +++ b/mq/kafka/kafka.md @@ -45,8 +45,9 @@ log分区分布在Kafka集群的服务器上,每个服务器处理对共享分 > 通常的,topic含有较少数量的consumer group,每个consumer group都是一个“逻辑订阅者”。每个consumer group都有许多的消费者实例组成,从而实现容错性和可拓展性。 > 上述consumer group整体作为一个订阅者,**在此语义中订阅者并非是单个进程,而是一个由消费者实例组成的集群** -在Kafka中,“消费”操作的实现方式是通过将分区日志根据消费者实例进行划分,故而每个实例在任何时间点对于其分配到的期间都是唯一的消费者。 -维护consumer group中成员的过程是由Kafka协议动态处理的,如果新的消费者实例加入到consumer group中,它们会接管从其他group成员中获取到的分区区间;如果现有消费者实例宕机,那么宕机实例的分区区间将会被分配给其他的消费者实例。 +在Kafka中,“消费”操作的实现方式是通过将分区根据消费者实例进行划分,故而每个实例在任何时间点对于其分配到的分区都是唯一的消费者。 +> 一个消费者实例可能会被分配到多个分区,但是任何一个分区,其对应的消费者实例只能有一个 +维护consumer group中成员的过程是由Kafka协议动态处理的,如果新的消费者实例加入到consumer group中,它们会接管从其他group成员中获取到的分区;如果现有消费者实例宕机,那么宕机实例的分区将会被分配给其他的消费者实例。 ### multi-tenancy(多租户) 可以将部署Kafka作为多租户的解决方案。可以通过配置哪些topic可以产生和消费数据来启用多租户。这些操作也支持配额。 ### Guarantees @@ -291,3 +292,22 @@ Kafka支持GZIP,LZ4,ZStandard压缩协议。 #### 异步发送 批量处理是提高性能的重要因素之一,为了支持批量处理,Kafka生产者会在内存中累计数据并在单个请求中发送更大的批数据。批处理可以被配置为累计不超过固定数量的消息或不超过特定界限的延迟(例如64K,10ms)。 ### 消费者 +#### 静态成员 +静态成员用于提升基于group rebalance协议应用的性能。rebalance协议依赖于组协调器,组协调器用于为组成员分配实体id。组协调器产生的实体id是短暂的,并且当成员重启并重新加入到组之后,实体id会发生变化。对于基于consumer的app,上述“动态成员”可能会造成在应用周期性重新启动时大量任务会被新分配给其他消费者实例。 +由于上述缺点,Kafka group管理协议允许组成员提供持久的实体id,基于这些id,组成员身份保持不变,故而rebalance不会被触发。 +如果想要使用静态成员: +- 将`ConsumerConfig#GROUP_INSTANCE_ID_CONFIG`设置为一个该组中唯一的值,不与同组其他消费者实例重复 +#### 消息传递语义 +Kafka在生产者和消费者之间提供了如下语义保证: +- at most once:消息可能丢失,但是消息永远不会被重复传递 +- at least once:消息永远不会丢失,但是消息可能被重复传递 +- Exaclty once:每条被传输一次并且只能被传输一次 + +可以将上述问题拆分为两个问题:发送消息的持久性保证和消费消息的保证。 +Kafka的语义是直截了当的,当消息被发布时,有一个消息被提交到log。只要消息被提交,且有一个包含消息所写入分区的broker存活,那么消息就不会被丢失。 +> 如果一个生产者尝试发布一条消息,并且遭遇到了网络错误,那么生产者无法确定网络错误发生在消息提交之前或之后。 + +在0.11.0.0之前,如果一个生产者没有接收到消息已经成功被提交的相应,那么生产者会重新发送该消息。这种实现提供了at-least-once的语义,如果前一次消息已经被写入到log中,那么重新发送的重复消息仍会被重复写入到log中。 +自从0.11.0.0开始,kafka生产者还支持幂等传输选项,幂等传输会保证消息的重复发送并不会导致log中存在重复条目。为了实现幂等传输,broker会分配给每个生产者一个id,并且通过和每条消息一起发送的序列号来判断去除重复消息。**同时,从0.11.0.0开始,生产者支持以类似事务的方式向多个topic分区发送多条消息:要么所有的消息被成功写入,要么所有的消息都未被写入。** +但是,并非是所有的用例都需要如此严格的保证。对于延迟敏感的场景,生产者可以指定其期望持久性级别。如果生产者指定其需要等待消息被提交,那么可能会需要10ms;但是生产者也可以指定异步发送消息或只需要等待到leader broker收到该信息(followers不用收到)。 +