第十四周 消息队列之Kafka从入门到小牛-3
Kafka核心之存储和容错机制
存储策略
1 | 在kafka中每个topic包含1到多个partition,每个partition存储一部分Message。每条Message包含三个属性,其中有一个是offset。 |

1 | 图中左侧就是索引,右边是segment文件,左边的索引里面会存储每一个segment文件中第一条消息的偏移量,由于消息的偏移量都是递增的,这样后期查找起来就方便了,先到索引中判断数据在哪个 |
容错机制
Broker节点宕机
1 | 当Kafka集群中的一个Broker节点宕机,会出现什么现象? |
1 | 我们可以先通过zookeeper来查看一下,因为当kafka集群中的broker节点启动之后,会自动向zookeeper中进行注册,保存当前节点信息 |

1 | 此时发现zookeeper的/brokers/ids下面只有2个节点信息 |

1 | 然后再使用describe查询topic的详细信息,会发现此时的分区的leader全部变成了目前存活的另外两个节点 |

新增一个Broker节点
1 | 当Kafka集群中新增一个Broker节点,会出现什么现象? |
1 | 此时到zookeeper中查看一下 |

1 | 发现broker.id为0的这个节点信息也有了 |

1 | 但是启动后有个问题:发现新启动的这个节点不会是任何分区的leader?怎么重新均匀分配呢? |
1 | 2、手动执行: |

Kafka生产消费者实战
1 | 前面我们使用基于console的生产者和消费者对topic实现了数据的生产和消费,,这个基于控制台的生产者和消费者主要是让我们做测试用的 |
Kafka Java代码编程
Java代码实现生产者代码

1 | 先创建maven项目, db_kafka |
1 | 开发生产者代码 |
1 | package com.imooc.kafka; |
Java代码实现消费者代码
1 | package com.imooc.kafka; |
启动
1 | 注意: |

1 | 再开启生产者,生产者会生产一条数据,然后就结束 |

1 | 此时回到kafka的消费者端就可以看到消费出来的数据了 |

1 | 所以这个时候我们发现,新产生的数据我们是可以消费到的,但是之前的数据我们就无法消费了,那下面我们来分析一下这个问题 |
消费者代码扩展
1 | //================================================== |
1 | 此时我们来验证一下, |
1 | 注意:消费者消费到数据之后,不要立刻关闭程序,要至少等5秒,因为自动提交offset的时机是5秒提交一次 |
1 | 将auto.offset.reset置为earliest,修改一下group.id的值,相当于使用一个新的消费者,验证一下,看是否能把这个topic中的所有数据都取出来,因为新的消费者第一次肯定是获取不到offset信息的, |
1 | ConsumerRecord(topic = hello, partition = 2, leaderEpoch = 0, offset = 0, Cre |

1 | 此时,关闭消费者(需要等待5秒,这样才会提交offset),再重新启动,发现没有消费到数据,说明此时就 |
1 | 最后来处理一下程序输出的日志警告信息,这里其实示因为缺少依赖日志依赖 |
1 | <dependency> |
1 | log4j.rootLogger=info,stdout |
Consumer消费offset查询
1 | kafka0.9版本以前,消费者的offset信息保存在zookeeper中 |

1 | 如何查询保存在kafka中的Consumer的offset信息呢? |
1 | 具体查看某一个consumer group的信息 |
1 | [root@bigdata01 kafka_2.12-2.4.1]# bin/kafka-consumer-groups.sh --describe --bootstrap-server localhost:9092 --group con-1 |

1 | partition:是指消费者消费了哪些分区 |
1 | 此时再执行一次生产者代码,生产一条数据,重新查看一下这个消费者的offset情况 |

1 | 如何分析生产的数据能不能及时消费掉:查看lag |
Consumer消费顺序
1 | 当一个消费者消费一个partition时候,消费的数据顺序和此partition数据的生产顺序是一致的 |

Kafka的三种语义
1 | kafka可以实现以下三种语义,这三种语义是针对消费者而言的: |
至少一次:at-least-once
1 | 这种语义有可能会对数据重复处理 |

至多一次:at-most-once
1 | 这种语义有可能会丢失数据 |
仅一次:exactly-once
1 | 这种语义可以保证数据只被消费处理一次。 |