Kafka基础教程(一):认识Kafka
Kafka是Apache下的一个子项目,是一个高性能跨语言分布式发布/订阅消息队列系统,吞吐速率非常快,可以作为Hadoop的日志收集。Kafka是一个完全的分布式系统,这一点依赖于Zookeeper的分布式实现。
本文为新手准备,从Kafka的一些术语概念方面去认识Kafka。
Broker
Kafka是基于Zookeeper实现的一个分布式系统,它的每一个分布式节点称为Broker。一般的,我们搭建的kafka节点数不会少于3台,具体需要多少依据业务量而定。
Topic
Topic是主题的意思,Kafka规定每个消息都应该有个主题,Topic可以理解为对消息的一个分类,比如用户注册使用一个Topic,用户下单应该使用另外一个Topic。
Broker和Topic没有包含的含义,一个Broker下面可以存在多个Topic的消息,而一个Topic的消息可以保存在一个或者多个Broker中。
Partition
Partition是分区,其实这就是Kafka的队列,Partition中的数据是具有顺序的,数据按照顺序进行消费,但是不同Partition中数据丢失了顺序性。
创建Topic时,可以指定Partition数,一个Topic至少有一个Partition,kafka在接收到生产者发送的消息之后,会根据会根据Paritition机制将消息并行的存储到不同的Partition中,这样就提高了吞吐量。
如果我们需要严格控制消息的顺序,那么可以创建只包含一个Partition的Topic,或者在发布消息和消费消息时,指定发布或者消费的Partition。
Replication
Replication是Topic的副本,一个Topic可以有多个副本,一个Topic下有多个Partition,每个Partition在每个副本中有对应的Partition副本,因为Topic副本之间需要保持数据的一致性,因此这些Partition之间也就形成和Zookeeper一样的Leader-Follower集群结构,与Zookeeper不同的是,对于数据的读写操作都在Leader中,Follower副本只是当Leader副本挂了后才重新选取Leader,Follower并不向外提供服务。
为了保证高可用(HA),Kafka会将Partition和它的副本均匀的保存在集群的Broker中,因此一般设置副本数不超过集群Broker节点数,最好是副本数等于集群节点数,使得集群中每个Broker都保存有Partition,这也是Kafka默认的做法。
Producer
Producer即生产者,生产者将消息发布到Topic中,Kafka根据自己的机制将消息发布到对应的Partition中。生产者也可以指定消息存发布的Partition。
Consumer
Consumer即消费者,消费者从Topic或者Topic指定的Partition中获取消息进行消费。
Consumer Group
每个Consumer可以指定一个Group Name,相同Group Name的Consumer视为一个Group。在开发过程中,同一Group Name的Consumer应该实现相同功能!如果Consumer不指定Group Name,那么它属于默认的那个Group。
Consumer以Group的形式从Topic中获取消息进行消费,准确说是从某个Partition中获取消息进行消费。一个Group下会有一个或者多个Consumer,而Partition中的每个消息只会被同一Group(中的某一个Consumer)消费一次,因此如果想要多个Consumer都可以对同一个消息进行消费,需要设置它们的GroupName不一样就可以了。
Offset
Offset即偏移,偏移是Partition对Consumer Group而言的,当某个Consumer成功消费消息之后,Kafka会标记该Consumer对应的Group对于此Partition的Offset加1,也就是偏移一个单位,因此该Group下的其他Consumer就消费不到这个消息了。
ISR(in-sync replicas)
上面有提到,Partition可能会有多个Partition副本,然后这些Partition之间也就形成和Zookeeper一样的Leader-Follower集群结构,只不过Leader负责读写,Follower只是同步数据备用。既然是集群,那就涉及数据同步问题。
每个Partition的Leader会记录和维护一个与它保持数据同步的Replication集合(Follower),这个集合称为ISR,每个Partition都会有一个与它对应的ISR。当Leader接收到消息后,会等待Follower同步数据,当ISR中的所有Replication都确认已同步数据完成后,Leader就会认为消息已提交。
当Leader挂掉了,Replication集合对应的Follower就会重新选举生成新的Leader,因为新Leader与原Leader保持数据同步,因此这样就避免了数据丢失。如果Replication集合为空,Leader挂了就等于数据丢失了,因此Replication是很有必要的。
ISR由Leader维护,而判断一个Replication是否有效,主要看它是否通过Zookeeper连接并能及时的从Leader中同步数据(超时时间由server.properties中replica.lag.time.max.ms配置),而且还要同步的数据不能与Leader相差太多(消息个数由server.properties中replica.lag.max.messages配置)。
ACK
Kafka的ACK机制,指的是Producer的消息发送确认机制,这直接影响到Kafka集群的吞吐量和消息可靠性。这个可靠性级别由request.required.acks来申明,它有3个可选值:0,1,-1
0:当Producer将消息发布到Leader之后,无需等待Leader确认,可以继续发送下一条消息,这样就提高了发送效率,但是消息可靠性最低。
1:当Producer将消息发布到Leader之后,只需等待Leader确认,而不管ISR中是否已经完成数据同步,这也是Kafka默认的Ack机制。但是不保证消息一定发送成功,比如Leader收到消息并确认后还未进行同步数据就挂了。
-1:当Producer将消息发布到Leader之后,需要等到ISR中所有的Replication全部完成数据同步确认才算消息发送成功,这样做消息可靠性最高。
当Ack=-1时,往往需要结合min.insync.replicas(默认值为1)一起使用,这是因为ISR中的Replication由Leader维护,个数可能会减少到0,这是ISR是一个空集合,此时Ack=-1和Ack=1是同一种情况,而min.insync.replicas表示ISR中的Replication副本个数,当ISR中的Replication个数少于此配置时,就表示消息发布失败。
Key
Key是Kafka消息的路由,Producer在发布消息时可以指定一个路由Key,当Kafka收到消息时,会按照一定的规则选择消息的Partition:
1、如果发布时制定了Partition,则直接使用 2、如果未指定Partition,但是指定了Key值,那么根据Key值通过一些规则算法计算消息发布的Partition
总结
Kafka是基于发布-订阅模式的分布式消息服务系统,将上面的概率连接起来就是:
发布
当我们的应用连接到Kafka集群的一个或者多个Broker节点往某个Topic(或者某个Topic的Partition)发布消息时,Kafka收到消息后会根据它的路由Key等信息得到Partition,然后将消息转发到该Partition的Leader,然后Leader会根据ISR机制记录消息,根据Ack机制对Producer做出响应。
消费
当我们的应用连接到Kafka集群的一个或者多个Broker节点从多个Topic(或者Topic的Partition)中订阅消息时,可以指定当前消费者所属的群组(Group Name),多个群组(Group)可以订阅同一个Topic,每个群组都会受到消息,但是一个消息只会被同一Group中的某个Consumer消费掉,当消息被成功消费掉之后,Kafka就会标记与当前Consumer对应的Group和消息所属的Partition对应的Offset加1。