kafka
组件
broker
kafka集群中包含一个或多个服务器,服务器节点为broker
broker存储topic的数据。如果某topic有N个partition,集群有N个broker,那么每个broker存储该topic的一个partition。
如果某topic有N个partition,集群有(N+M)个broker,那么其中有N个broker存储该topic的一个partition,剩下的M个broker不存储该topic的partition数据。
如果某topic有N个partition,集群中broker数目少于N个,那么一个broker存储该topic的一个或多个partition。在实际生产环境中,尽量避免这种情况的发生,这种情况容易导致Kafka集群数据不均衡。
每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)
类似于数据库的表名
Partition
topic中的数据分割为一个或多个partition。每个topic至少有一个partition。每个partition中的数据使用多个segment文件存储。partition中的数据是有序的,不同partition间的数据丢失了数据的顺序。如果topic有多个partition,消费数据时就不能保证数据的顺序。在需要严格保证消息的消费顺序的场景下,需要将partition数目设为1。
producer
生产者即数据的发布者,该角色将消息发布到Kafka的topic中。broker接收到生产者发送的消息后,broker将该消息追加到当前用于追加数据的segment文件中。生产者发送的消息,存储到一个partition中,生产者也可以指定数据存储的partition。
consumer
消费者可以从broker中读取数据。消费者可以消费多个topic中的数据。
consumer group
每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
leader
每个partition有多个副本,其中有且仅有一个作为Leader,Leader是当前负责数据的读写的partition。
follower
Follower跟随Leader,所有写请求都通过Leader路由,数据变更会广播给所有Follower,Follower与Leader保持数据同步。如果Leader失效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个Follower。
总结
1,一条消息最终落入到某个主题的某个分区
2,客户端
生产者
消费者
3,生产者
消息的区分选择
a、null key:轮询所有分区,负载均衡
b、key:hash(key)%分区数
c、指定分区:如果使用这种情况,那么以上两者无效
d、自定义分区:取决于如何实现
消息的成功发送
a、不等待集群的反馈
-1
b、等待集群的反馈:按照ack来确认消息是否发送成功
1
0:等待leader的反馈
all:等待所有副本的反馈
4、消费者
重复消费
a、重复消费:不同消费组
b、不重复消费:同一个消费组
不会在同一时刻,同一组内,多个消费者同时消费数据
一个分区的数据,只能交给一个消费者消费
一个消费者,可以消费多个分区中的数据,可以夸主题
负载均衡
a、尽可能的将多个分区,分配给不同的消费者消费
消费顺序
a、保证一个分区中的数据消费过程是有序的
手段:
将所有数据指定到某个分区中
只设置一个分区
API
producerAPI
KafkaProducer<String, String> producer = new KafkaProducer<String, String>(properties);
comstomAPI
KafkaProducer<String,String> producer = new KafkaProducer<>(props)
分区API
接口org.apache.kafka.clients.producer.Partitioner
int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster)
拦截器API
接口org.apache.kafka.clients.producer.ProducerInterceptor
onSend()处理消息
onAcknowledgement()处理返回消息
kafkaStreamsAPI
接口org.apache.kafka.streams.processor.Processor<byte[],byte[]>
init(ProcessorContext context)
process(byte[] key,byte[] value)每条数据
context.forward
puctuate(long timestamp)周期性