- Kafka 是什么?主要应用场景有哪些?
流平台具有三个关键功能:消息队列、容错的持久方式存储记录消息流、流式处理平台
Kafka 主要有两大应用场景:消息队列和数据处理
- Kafka 的消息模型
队列模型
发布-订阅模型
发布者发布一条消息,该消息通过主题传递给所有的订阅者,在一条消息广播之后才订阅的用户则是收不到该条消息的。
什么是Producer、Consumer、Broker、Topic、Partition
Kafka 将生产者发布的消息发送到 Topic(主题) 中,需要这些消息的消费者可以订阅这些 Topic(主题),如下图所示:
- Kafka 比较重要的几个概念:
Producer(生产者) : 产生消息的一方。
Consumer(消费者) : 消费消息的一方。
Broker(代理) : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个 Kafka Cluster。
同时每个 Broker 中又包含了 Topic 以及 Partition 这两个重要的概念:
Topic(主题) : Producer 将消息发送到特定的主题,Consumer 通过订阅特定的 Topic(主题) 来消费消息。
Partition(分区) : Partition 属于 Topic 的一部分。一个 Topic 可以有多个 Partition ,并且同一 Topic 下的 Partition 可以分布在不同的 Broker 上,这也就表明一个 Topic 可以横跨多个 Broker 。Kafka 中的 Partition(分区) 实际上可以对应成为消息队列中的队列
-
Kafka 的多副本机制了解吗?带来了什么好处
分区(Partition)中的多个副本之间会有一个叫做 leader ,其他副本称为 follower。我们发送的消息会被发送到 leader 副本,然后 follower 副本才能从 leader 副本中拉取消息进行同步。
leader挂了从follower选取。 -
Poducer消息partitioning策略
轮询策略、随机策略、按消息键保序策略(同一个消息的key保证发送到同一个partition) -
kafka的消息消费分配策略
Range策略:把主题的分区和消费线程数排序,分区平均到每一个线程上消费
roundrobin: -
Kafka 如何保证消息的消费顺序?
(推荐)发送消息的时候指定 key/Partition
-
生产者丢失消息的情况
1、使用get方法获取send的结果
2、增加重试机制 -
消费者丢失消息的情况
维持先消费消息(阅读),再更新位移(书签)的顺序 -
Kafka 弄丢了消息
设置所有副本收到消息或者部分副本收到消息才算成功,Partition有一个多副本机制。 -
Kafka无消息丢失的配置:
不要使用producer.send(msg),而要使用producer.send(msg, callback)。记住,一定要使用带有回调通知的send方法。
设置acks = all。acks是Producer的一个参数,代表了你对“已提交”消息的定义。如果设置成all,则表明所有副本Broker都要接收到消息,该消息才算是“已提交”。这是最高等级的“已提交”定义。
设置retries为一个较大的值。这里的retries同样是Producer的参数,对应前面提到的Producer自动重试。当出现网络的瞬时抖动时,消息发送可能会失败,此时配置了retries > 0的Producer能够自动重试消息发送,避免消息丢失。
设置unclean.leader.election.enable = false。这是Broker端的参数,它控制的是哪些Broker有资格竞选分区的Leader。如果一个Broker落后原先的Leader太多,那么它一旦成为新的Leader,必然会造成消息的丢失。故一般都要将该参数设置成false,即不允许这种情况的发生。
设置replication.factor >= 3。这也是Broker端的参数。其实这里想表述的是,最好将消息多保存几份,毕竟目前防止消息丢失的主要机制就是冗余。
设置min.insync.replicas > 1。这依然是Broker端参数,控制的是消息至少要被写入到多少个副本才算是“已提交”。设置成大于1可以提升消息持久性。在实际环境中千万不要使用默认值1。
确保replication.factor > min.insync.replicas。如果两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了。我们不仅要改善消息的持久性,防止数据丢失,还要在不降低可用性的基础上完成。推荐设置成replication.factor = min.insync.replicas + 1。
确保消息消费完成再提交。Consumer端有个参数enable.auto.commit,最好把它设置成false,并采用手动提交位移的方式。就像前面说的,这对于单Consumer多线程处理的场景而言是至关重要的。
- Kafka 如何保证消息不重复消费
kafka出现消息重复消费的原因:
网络链接等等原因让 Kafka 认为服务假死
解决方法:消费消息服务做幂等校验
-
消息交付可靠性保障,是指Kafka对Producer和Consumer要处理的消息提供什么样的承诺
常见的承诺有以下三种:kafka是第二种
最多一次(at most once):消息可能会丢失,但绝不会被重复发送。
至少一次(at least once):消息不会丢失,但有可能被重复发送。
精确一次(exactly once):消息不会丢失,也不会被重复发送。
那么Kafka是怎么做到精确一次的呢?通过两种机制:幂等性(Idempotence)和事务(Transaction)。
幂等性Producer
实现单分区的幂等性,设置参数,kafka可以自动去重,有字段标识,如果字段相同就去重复。
事务型Producer
通过参数控制,事务型Producer能够保证将消息原子性地写入到多个分区中。这批消息要么全部写入成功,要么全部失败。 -
20道经典的Kafka面试题详解