Kafka原理

Kafka的架构: enter image description here

enter image description here

 

1. 持久化: 通过将数据持久化到硬盘以及replication防止数据丢失。

2.消息状态: 被处理的状态是在consumer端维护,而不是由server端维护。

3. 生产者、消费者只从Partition-leader 集群节发收消息。

4. 生产者通过负载策略发到不同的Partition-leader ,消费者可以连接多个Partition-leader,但一个Partition-leader,只允许topic的同一个topic组里的一个Consumer连接。

一、Broker(节点):

由于每个Topics划分为一个或者多个Partition。每个Partition-leader 分布在不同的Broker(节点)中,Producer消息生产者只会向Partition-leader发送消息,由Partition-leader向其它Patition-follower同步数据。 实现消息发送的负载均衡。

image_1c43kfoau1r6lqq8k46moo1ijm9.png-97.7kB

image_1c41qsc4d1tr5gum1rg3s314991j.png-45.8kB

1.Broker:配置文件server.properties 
   1、 配置:Log Flush Policy
     #log.flush.interval.messages=10000   一个分区的消息数阀值
     #log.flush.interval.ms=1000    

   减少磁盘写入的次数,broker会将消息暂时buffer起来,当消息的个数达到一定阀值或者过了一定的时间间隔时,再flush到磁盘。
   2、配置:Log Retention Policy 
     log.retention.hours=168 
     #log.retention.bytes=1073741824
     log.retention.check.interval.ms=30

kafka的消息保存一定时间(通常为7天)后会被删除。

 二、Producer生产者:

 Producer发送到Topic的数据是有key/value键值对组成的,Kafka根据key的不同的值决定数据发送到不同的Partition

image_1c43llqh611la1mkn18ir9tb1uh4m.png-48.7kB

 

1. 负载均衡: producer将会和Topic下所有partition leader保持socket连接; 

 2. 路由算法:producer客户端决定.比如可以采用"random""key-hash""轮询"等算法,将消息路由到哪个partition-leader上.

 3. 集群关系:partition leader的位置(host:port)注册在zookeeper中,producer作为zookeeper client,已经注册了watch用来监听partition leader的变更事件.

4. 异步批量发送:将多条消息暂且在客户端buffer起来,并将他们批量的发送到broker.

5. Producer配置文件:producer.properties
    1、自定义partition: Producer也根据用户设置的算法来根据消息的key来计算输入哪个partition:partitioner.class
    2、异步或者同步发送:producer.type
    同步:发送方发出数据后,等接收方发回响应以后才发下一个数据的通讯方式。  
    异步:发送方发出数据后,不等接收方发回响应,接着发送下个数据的通讯方式。
    3、批量发送:
    Kafka producer的异步发送模式允许进行批量发送,先将消息缓存在内存中,然后一次请求批量发送出去。
   具体配置queue.buffering.max.ms、queue.buffering.max.messages默认值分别为5000和10000

6.  设置 acks = all。acks 是 Producer 的一个参数,代表了你对“已提交”消息的定义。如果设置成 all,则表明所有副本 Broker 都要接收到消息,该消息才算是“已提交”。这是最高等级的“已提交”定义。

acks= 0时不需要关心是不是收到服务端的ack, ack =1 需要收到服务端的ack,(只需要一个leader ,breaker服务器 )

三、Consumer消息者: 

Kafka 保证同一 consumer group 中只有一个 consumer 可消费某条消息,实际上,Kafka 保证的是稳定状态下每一个 consumer 实例只会消费某一个或多个特定的数据,而某个 partition 的数据只会被某一个特定的 consumer 实例所消费。

 

四、Topic & Partition:

enter image description here

 1.segment文件结构:

segment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为segment索引文件和数据文件。

.index”索引文件存储大量的元数据,“.log”数据文件存储大量的消息。索引文件中的元数据指向对应数据文件中 message 的物理偏移地址。

2.消息格式:

message length : 4 bytes (value: 1+4+n)
"magic" value : 1 byte 
crc : 4 bytes 
payload : n bytes  (消息数据)

 

五、全程解析(Producer-kafka-consumer)

1.producer 发布消息:

producer 采用 push 模式将消息发布到 broker,每条消息都被 append 到 patition 中,属于顺序写磁盘,producer 发送消息到 broker 时,会根据分区算法选择将其存储到哪一个 partition。

其路由机制为:

  1. 指定了 patition,则直接使用;
  2. 未指定 patition 但指定 key,通过对 key 进行 hash 选出一个 patition;
  3. patition 和 key 都未指定,使用轮询选出一个 patition。

写入流程:

  1. producer 先从 ZooKeeper 的 "/brokers/.../state" 节点找到该 partition 的leader;
  2. producer 将消息发送给该 leader;
  3. leader 将消息写入本地 log;
  4. followers 从 leader pull 消息,写入本地 log 后 leader 发送 ACK;
  5. leader 收到所有 ISR 中的 replica 的 ACK 后,增加 HW(high watermark,最后 commit 的 offset) 并向 producer 发送 ACK;

2.Broker 存储消息:

物理上把 topic 分成一个或多个 patition,每个 patition 物理上对应一个文件夹(该文件夹存储该 patition 的所有消息和索引文件)

3 Consumer 消费消息:

consumer 采用 pull 模式从 broker 中读取数据。

一个消息只能被 group 内的一个 consumer 所消费,且 consumer 消费消息时不关注 offset,最后一个 offset 由 ZooKeeper 保存(下次消费时,该group 中的consumer将从offset记录的位置开始消费)。

注意:

  1. 如果消费线程大于 patition 数量,则有些线程将收不到消息;
  2. 如果 patition 数量大于消费线程数,则有些线程多收到多个 patition 的消息;
  3. 如果一个线程消费多个 patition,则无法保证你收到的消息的顺序,而一个 patition 内的消息是有序的。

 

对于 Kafka 而言,pull 模式更合适,它可简化 broker 的设计,consumer 可自主控制消费消息的速率,同时 consumer 可以自己控制消费方式——即可批量消费也可逐条消费,同时还能选择不同的提交方式从而实现不同的传输语义。

五、参考:

1. https://gitbook.cn/books/5ae1e77197c22f130e67ec4e/index.html

2.https://blog.csdn.net/lp284558195/article/details/80297208

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值