Kafka-原理解析

1、基础知识

1.1、存储结构图

1.2、topic结构

1.2.1、语法

/brokers/topics/[topic]

1.2.2、topic结构

[zk: 192.168.10.30:2181(CONNECTED) 2] ls /brokers
[ids, seqid, topics]

[zk: 192.168.10.30:2181(CONNECTED) 1] ls /brokers/topics
[__consumer_offsets, kafkatest]

[zk: 192.168.10.30:2181(CONNECTED) 3] get /brokers/topics/kafkatest
{"partitions":{"0":[1,3,2],"1":[2,1,3],"2":[3,2,1]},"topic_id":"dpeV7n3fSyehh-ebygbwaQ","adding_replicas":{},"removing_replicas":{},"version":3}

# 属性解析
version: 当前的版本号
partitions: 分区的信息

1.3、partition结构

1.3.1、语法

/brokers/topics/[topic]/partitions/[partitionId]/state

1.3.2、partition结构

[zk: 192.168.10.30:2181(CONNECTED) 4] ls /brokers/topics/kafkatest 
[partitions]

[zk: 192.168.10.30:2181(CONNECTED) 5] ls /brokers/topics/kafkatest/partitions 
[0, 1, 2]

[zk: 192.168.10.30:2181(CONNECTED) 6] get /brokers/topics/kafkatest/partitions/0
null

[zk: 192.168.10.30:2181(CONNECTED) 7] get /brokers/topics/kafkatest/partitions/0/state
{"controller_epoch":14,"leader":1,"version":1,"leader_epoch":0,"isr":[1,3,2]}

# 属性解析
controller_epoch: 表示kafka集群中的中央控制器选举次数,
leader: 表示该partition选举leader的brokerId,
version: 版本编号默认为1,
leader_epoch: 该partition leader选举次数,
isr: [同步副本组brokerId列表]

1.4、broker信息

1.4.1、语法

/brokers/ids/[0...N]

1.4.2、broker结构

[zk: 192.168.10.30:2181(CONNECTED) 8] ls /brokers 
[ids, seqid, topics]

[zk: 192.168.10.30:2181(CONNECTED) 9] ls /brokers/ids 
[1, 2, 3]

[zk: 192.168.10.30:2181(CONNECTED) 10] get /brokers/ids/1 
{"features":{},"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://192.168.10.30:9092"],"jmx_port":-1,"port":9092,"host":"192.168.10.30","version":5,"timestamp":"1685678338970"}
[zk: 192.168.10.30:2181(CONNECTED) 11] get /brokers/ids/2
{"features":{},"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://192.168.10.31:9092"],"jmx_port":-1,"port":9092,"host":"192.168.10.31","version":5,"timestamp":"1685678356448"}
[zk: 192.168.10.30:2181(CONNECTED) 12] get /brokers/ids/3
{"features":{},"listener_security_protocol_map":{"PLAINTEXT":"PLAINTEXT"},"endpoints":["PLAINTEXT://192.168.10.32:9092"],"jmx_port":-1,"port":9092,"host":"192.168.10.32","version":5,"timestamp":"1685678358975"}

# 属性解析:
jmx_port:  jmx端口号,
timestamp: kafka broker初始启动时的时间戳,
host:      主机名或ip地址,
version:   版本编号默认为1,
port: kafka broker的服务端端口号,由server.properties中参数port确定

1.5、控制器

1.5.1、语法

/controller  # 存储center controller中央控制器所在kafka broker的信息

1.5.2、控制器结构

[zk: 192.168.10.30:2181(CONNECTED) 13] ls /controller
[]

[zk: 192.168.10.30:2181(CONNECTED) 14] get /controller
{"version":2,"brokerid":1,"timestamp":"1685678339168","kraftControllerEpoch":-1}

# 属性解析
 version:   版本编号默认为1,
 brokerid:  kafka集群中broker唯一编号,
 timestamp: kafka broker中央控制器变更时的时间戳

1.6、控制策略

1.6.1、语法

/controller_epoch # 此值为一个数字,每次center controller变更controller_epoch值就会 + 1

 

 

1.6.2、控制策略结构

[zk: 192.168.10.30:2181(CONNECTED) 15] ls /controller_epoch 
[]
[zk:
192.168.10.30:2181(CONNECTED) 16] get /controller_epoch 14

1.7、消费者

# 消费者信息:
/consumers/[groupId]/ids/[consumerIdString]

# 每个consumer都有一个唯一的ID,此id用来标记消费者信息消费者管理者:
/consumers/[groupId]/owners/[topic]/[partitionId]

2、流程梳理

2.1、发布消息

2.1.1、基本逻辑

producer 采用 push 模式将消息发布到 broker,broker接收到消息,会根据分区算法选择将其存储到哪一个 partition,然后消息都被 append 到指定的 patition 中。

2.1.2、细节逻辑

 producer 先从 zookeeper 的 "/brokers/.../state" 节点找到该 partition 的 leader 
 producer 将消息发送给该 leader 
 leader 将消息写入本地 log 
 followers 从 leader pull 消息,写入本地 log 后 leader 发送 ACK 
 leader 收到所有 ISR 中的 replica 的 ACK 后,更新 commit 并向 producer 发送 ACK

2.2、broker保存消息

2.2.1、基本逻辑

默认情况下,一个 topic 分成一个或多个 patition(num.partitions),每个 patition 就是一个文件夹,保存了所有消息和索引文件。
 
这些数据不会无限制的存储下去,会在某个时候自动清空,这是由以下两种配置决定的。
基于时间:log.retention.hours=168 
基于大小:log.retention.bytes=1073741824

2.2.2、查询保存的目录

# ll /usr/local/kafka/logs/ | grep kafkatest
drwxr-xr-x  2 root root   4096 Jun  2 12:49 kafkatest-0/
drwxr-xr-x  2 root root   4096 Jun  2 12:49 kafkatest-1/
drwxr-xr-x  2 root root   4096 Jun  2 14:40 kafkatest-2/


# tree /usr/local/kafka/logs/kafkatest-0/ /usr/local/kafka/logs/kafkatest-0/ ├── 00000000000000000000.index ├── 00000000000000000000.log ├── 00000000000000000000.timeindex ├── leader-epoch-checkpoint └── partition.metadata

2.3、topic逻辑

2.3.1、新增逻辑

controller 在 ZK 的 /brokers/topics 节点上注册 watcher
   - 当 topic 被创建,则 controller 会通过 watch 得到该 topic 的partition/replica 分配。
 
controller从 /brokers/ids 读取当前所有可用的 broker 列表,对于 set_p 中的每一个partition:
   - 从分配给该 partition 的所有 replica中任选一个可用的 broker 作为新的 leader,并将AR设置为新的 ISR 
   - 将新的 leader 和 ISR 写入/brokers/topics/[topic]/partitions/[partition]/state 
controller 通过 RPC 向相关的 broker 发送 LeaderAndISRRequest。

2.3.2、删除逻辑

controller 在 ZK 的 /brokers/topics 节点上注册 watcher,
 - 当 topic 被删除,则 controller 会通过 watch 得到该 topic 的partition/replica 分配。
若 delete.topic.enable
=false,结束 - 否则 controller 注册在 /admin/delete_topics 上的 watch 被 fire,controller 通过回调向对应的 broker 发送 StopReplicaRequest。

2.4、broker故障

2.4.1、逻辑流程

controller 在 zookeeper 的 /brokers/ids/[brokerId] 节点注册 Watcher,当 broker 宕机时 zookeeper 会 fire watch
controller 从 /brokers/ids 节点读取可用broker 
controller决定set_p,该集合包含宕机 broker 上的所有 partition  对 set_p 中的每一个 partition 
   - 从/brokers/topics/[topic]/partitions/[partition]/state 节点读取 ISR 
   - 决定新 leader 
   - 将新 leader、ISR、controller_epoch 和 leader_epoch 等信息写入 state 节点
 通过 RPC 向相关 broker 发送 leaderAndISRRequest 命令

2.4.2、查看节点状态

tail  -f /usr/local/kafka/logs/controller.log

# kafka-topics.sh --describe --bootstrap-server 192.168.10.30:9092,192.168.10.31:9092,192.168.10.32:9092 kafkatest
...
Topic: kafkatest        TopicId: dpeV7n3fSyehh-ebygbwaQ PartitionCount: 3       ReplicationFactor: 3    Configs: 
        Topic: kafkatest        Partition: 0    Leader: 1       Replicas: 1,3,2 Isr: 1,3,2
        Topic: kafkatest        Partition: 1    Leader: 2       Replicas: 2,1,3 Isr: 2,1,3
        Topic: kafkatest        Partition: 2    Leader: 3       Replicas: 3,2,1 Isr: 3,2,1
posted @ 2023-06-02 18:19  小粉优化大师  阅读(5)  评论(0编辑  收藏  举报