面试题答案
一键面试Kafka 自身机制确保一致性
- 生产者方面
- acks 机制:
- 生产者发送消息时可以设置
acks
参数。当acks = 0
时,生产者发送完消息后不会等待任何来自 Kafka 集群的确认,这种情况下无法保证消息一定到达 Kafka 集群,可能会丢消息。 - 当
acks = 1
时,生产者会等待 Kafka 的 leader 副本确认收到消息。只要 leader 副本成功写入消息,就认为消息发送成功。如果此时 leader 副本在向 follower 副本同步消息前宕机,那么这条消息就会丢失,一致性无法保证。 - 当
acks = all
或acks = -1
时,生产者会等待所有同步中的副本(ISR 中的副本)都确认收到消息,才认为消息发送成功。这种方式能最大程度保证消息不会丢失,但可能会因为等待所有副本确认而降低性能。
- 生产者发送消息时可以设置
- 重试机制:生产者在发送消息失败时,会根据配置的重试次数进行重试。例如,如果因为网络短暂故障导致消息发送失败,通过重试有可能成功将消息发送到 Kafka 集群,从而保证消息不丢失,维持一致性。
- acks 机制:
- Kafka 集群方面
- 副本机制:Kafka 采用多副本机制来保证数据的可靠性和一致性。每个分区都有一个 leader 副本和多个 follower 副本。leader 副本负责处理读写请求,follower 副本从 leader 副本同步数据。
- ISR(In - Sync Replicas):只有与 leader 副本保持一定程度同步的 follower 副本才会被包含在 ISR 中。当 leader 副本宕机时,Kafka 会从 ISR 中选举一个新的 leader 副本。由于 ISR 中的副本数据相对一致,选举新 leader 后能最大程度保证数据一致性。例如,如果 leader 副本在写入一条消息后宕机,只要这条消息已经被 ISR 中的所有副本同步,那么新选举的 leader 副本中也会有这条消息。
- 消费者方面
- 位移管理:消费者通过偏移量(offset)来记录已消费消息的位置。偏移量是 Kafka 中每个分区内消息的唯一标识。消费者在消费消息后,会将偏移量提交。Kafka 提供了自动提交和手动提交两种方式。自动提交方式下,消费者定期将偏移量提交给 Kafka;手动提交则由开发者在合适的时机调用 API 提交偏移量。通过准确管理偏移量,消费者可以保证在重启或故障恢复后,从上次消费的位置继续消费,避免重复消费或漏消费消息,维持数据一致性。
结合外部手段确保一致性(以事务处理为例)
- Kafka 事务机制:Kafka 从 0.11.0.0 版本开始引入了事务支持。
- 事务初始化:生产者通过
initTransactions()
方法初始化事务。 - 事务开始:调用
beginTransaction()
方法开始一个事务。 - 消息发送:在事务内,生产者可以向多个分区发送消息。例如,在电商订单实时处理系统中,可能需要向订单信息分区、支付信息分区等多个分区发送与同一订单相关的消息。这些消息的发送操作都包含在事务内,要么全部成功,要么全部失败。
- 事务提交或回滚:如果消息发送成功,调用
commitTransaction()
方法提交事务;如果发送过程中出现错误,调用abortTransaction()
方法回滚事务。通过这种方式,确保了跨分区消息发送的原子性,保证了数据的一致性。例如,在电商场景中,如果订单信息发送成功但支付信息发送失败,通过回滚事务可以保证订单数据不会处于部分成功的不一致状态。
- 事务初始化:生产者通过
- 与外部系统事务协调:在电商订单实时处理系统中,可能还需要与外部系统(如数据库)进行交互。例如,在处理订单时,不仅要将订单消息发送到 Kafka,还需要更新数据库中的库存信息等。此时可以使用分布式事务解决方案(如两阶段提交协议、三阶段提交协议等)来协调 Kafka 与外部系统之间的事务。以两阶段提交协议为例,第一阶段(准备阶段),协调者(可以是应用程序本身)向所有参与者(如 Kafka 生产者和数据库)发送准备请求,参与者执行操作但不提交;第二阶段(提交阶段),如果所有参与者准备成功,协调者向所有参与者发送提交请求,否则发送回滚请求。这样可以确保 Kafka 消息发送与外部系统操作的一致性。