Kafka基础知识02 -- 集群操作和生产者的实现
一,Kafka集群操作
1. 搭建kafka集群(三个broker)
创建三个server.properties文件

通过命令来启动三台broker

校验是否启动成功
进入到zk中查看/brokers/ids中是否有三个znode(1,2,3)
2. 副本的概念
副本是为了为主题的分区创建多个备份,多个副本在kafka集群的多个broker中,会有一个副本作为leader,其他时follower。一般来说,有几个broker就有几个副本。(分区时物理上的划分)

leader: kafka的写和读的操作,都发生在leader上。leader负责把数据同步给follower。当leader挂了,经过主从选举,从多个follers选举产生一个新的leader。
每个partition都有一个broker作为leader. 消息发送方要把消息发送给哪个broker? 就看leader在哪个broker上。副本里的leader专门用来发送消息。接收到消息,其他follow通过poll的方式同步数据。
follower: 接收leader同步的数据。不提供读写
isr: 可以同步和已同步的节点会被存入到isr集合中。这里有一个细节:如果isr的节点性能较差,会被踢出isr集合。
replicas: 当前副本存在的broker节点
重点:集群中有多个broker,创建主题时可以指明主题有多个分区partition(把消息拆分到不同的分区中存储),可以为分区创建多个副本,不同的副本存放在不同的broker里。
3. 关于集群消息
1). 向集群发送消息

2). 指定消费组来消费消息

3). 分区消费组的集群消费细节

一个partition只能被一个消费组的一个消费者消费,目的是为了保证消费的顺序性, 但是多个partition的多个消费者消费的总的顺序性是得不到保证的,那么怎么做到保证消费的总顺序性呢?
partition的数量决定了消费组中消费者的数量,建议同一个消费组中消费者的数量不要超过partition的数量,否则多的消费者消费不到消息
如果消费者挂了,那么会触发rabalance机制,会让其他消费者来消费该分区
二,kafka的java客户端--生产者的实现
生产者的基本实现:
1. 引入依赖

2. 具体实现

3. 发送消息到指定分区上

4. 未指定分区,则会通过业务key的hash运算,算出消息往哪个分区上发

5. 生产者的同步发送消息

如果生产者发送消息没有收到ack,生产者会阻塞,阻塞到3s的时间,如果还没有收到消息,会进行重试,重试的次数3次。

6. 生产者的异步发送消息

异步发送,生产者发送完消息后就可以执行之后的业务,broker在收到消息后异步调用生产者提供的callback回调方法。

同步发送用的比较多,因为异步发送容易丢失数据。
7. 生产者中的ack配置
在同步发送的前提下,生产者在获得集群返回的ack之前会一直阻塞,那么集群什么时候返回ack呢?此时ack有三个配置:
ack=0:kafka-cluster不需要任何的broker收到消息,就立即返回ack给生产者,最容易丢消息,效率是最高的。
ack=1(默认):多副本之间的leader已经收到消息,并把消息写入到本地的log中,才会返回ack给生产者,性能和安全性是最均衡的。这种情况下,如果follower没有成功备份数据,而leader又挂掉,则消息会丢失。
ack=-1/all:里面有默认的配置min.insync.replicas=2(默认为1,推荐配置大于等于2),此时就需要leader和一个follower同步完成后,才会返回ack给生产者(此时集群中有2个broker已完成数据的接收),这种方式最安全,但性能最差。金融相关,跟钱打交道的场景会用到。


下面是关于ack的重试的配置(如果没有收到ack,就开启重试)

8. 关于消息发送的缓冲区
如果生产者有十万条消息,不可能与kafka建立十万次会话,这时需要了解缓冲区和本地线程的概念

kafka默认会创建一个消息缓冲区,用来存放要发送的消息,缓冲区是32m

kafka本地线程会去缓冲区中一次拉16k的数据,发送到broker

如果线程拉不到16k的数据,间隔10ms也会将已拉到的数据发到broker
