08 kafka

  1 Kafka概述

1.1 定义

● 基于发布/订阅模式消息队列(Message Queue)—— 传统

● 分布式事件流平台(event streaming platform)—— 最新定位

1.2 消息队列

1.2.1 传统消息队列的应用场景

1)引用场景

2)使用消息队列的好处

解耦

● 允许独立的扩展修改两边的处理过程。

可恢复性

● 部分组件失效,不影响整体系统。

缓冲

● 有助于控制和优化数据流经过系统的速度

● 解决生产消息和消费消息的处理速度不一致的情况

灵活性和峰值处理能力

● 使用消息队列能够使关键组件顶住突发的访问压力。

异步通信

● 用户把消息放入队列,并表示不想立即处理。

1.2.2 消息队列的两种模式

1)点对点模式(一对一)

● 消费者主动拉去数据,用后消除

● 一个消息只有一个消费者使用(Queue支持存在多个消费者)

2)发布/订阅模式(一对多)

● 优点:发布到topic的消息会被所有的订阅者消费

● 缺点:不断轮询,看看消息出来没(自助烧烤)

1.3 Kafka基础架构

Producer 消息生产者
Consumer 消息消费者
Consumer Group 消费组
Broker kafka服务器=broker, broker可以容纳多个topic
Topic 队列(先这样理解),生产者和消费者面向的都是一个topic
Partition 有序的队列一个topic可分布到多个broker上,一个topic可以分为多个parition
Replication 副本
leader ”主“,(读写)
follower ”从“,(同步数据),实时与leader副本保持同步

 

2 Kafka快速入门

2.1 安装部署

集群规划——Kafka下载

2.1.2 集群部署

解压——修改文件名——修改配置文件——配置环境变量——分发环境变量——分发安装包——修改brokerid——启动集群——关闭集群

配置文件修改内容

[atguigu@hadoop102 kafka]$ cd config/
[atguigu@hadoop102 config]$ vim server.properties
# broker的全局唯一编号,不能重复
broker.id=102
# 删除topic功能使能,当前版本此配置默认为true,已从配置文件移除
delete.topic.enable=true
# 处理网络请求的线程数量
num.network.threads=3
# 用来处理磁盘IO的线程数量
num.io.threads=8
# 发送套接字的缓冲区大小
socket.send.buffer.bytes=102400
# 接收套接字的缓冲区大小
socket.receive.buffer.bytes=102400
# 请求套接字的缓冲区大小(100M)
socket.request.max.bytes=104857600
# kafka运行日志(数据)存放的路径
log.dirs=/opt/module/kafka/datas
# topic在当前broker上的分区个数
num.partitions=1
# 启动时用于日志恢复和关闭时用于刷新的每个数据目录的线程数量
num.recovery.threads.per.data.dir=1
# segment文件保留的最长时间,超时将被删除
log.retention.hours=168
# 配置连接Zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181/kafka
启动kafka集群 bin/kafka-server-start.sh -daemon config/server.properties
关闭kafka集群 bin/kafka-server-stop.sh
-daemon daemon又称为守护进程,后台运行。

2.1.4 群起脚本

1)脚本编写

查看代码

#! /bin/bash
if (($#==0)); then
  echo -e "请输入参数:\n start  启动kafka集群;\n stop  停止kafka集群;\n" && exit
fi

case $1 in
  "start")
    for host in hadoop103 hadoop102 hadoop104
      do
        echo "---------- $1 $host 的kafka ----------"
        ssh $host "/opt/module/kafka/bin/kafka-server-start.sh -daemon /opt/module/kafka/config/server.properties"
      done
      ;;
  "stop")
    for host in hadoop103 hadoop102 hadoop104
      do
        echo "---------- $1 $host 的kafka ----------"
        ssh $host "/opt/module/kafka/bin/kafka-server-stop.sh /opt/module/kafka/config/server.properties"
      done
      ;;
    *)
        echo -e "---------- 请输入正确的参数 ----------\n"
        echo -e "start  启动kafka集群;\n stop  停止kafka集群;\n" && exit
      ;;
esac

2)脚本文件添加权限

[atguigu@hadoop102 bin]$ chmod +x kafka.sh

2.2 Kafka命令行操作

2.2.1 Topic相关命令操作

查看所有topic bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --list
创建topic bin/kafka-topics.sh --bootstrap-server hadoop:9092 --create --replication-factor 2 --partitions 1 --topic first
--bootstrap-server 指定broker节点(一个或多个)
--topic  定义topic名
--replication-factor  定义副本数
--partitions  定义分区数
删除topic bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --delete --topic first
查看topic详情 bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --describe --topic first
修改分区数 bin/kafka-topics.sh --bootstrap-server hadoop102:9092 --alter --topic first --partitions 3

注意:

● 副本数不可以修改

● 如果修改分区数,分区数只能增加,不能减少。

2.2.2 消息的生产和消费

生产消息 bin/kafka-console-producer.sh --broker-list hadoop102:9092 --topic first
--broker-list 指定集群地址
消费消息 bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first
bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092  --from-beginning --topic first
--from-beginning   会把主题中现有的所有的数据读取出来 (从offset为0开始消费)
指定消费组组 bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092  --from-beginning --group t1 --topic first
查看消费组记录 ./kafka-consumer-groups.sh --all-groups --all-topics --describe --bootstrap-server hadoop102:9092

3 Kafka架构深入

3.1 Kafka工作流程及文件存储机制

① Kafka消息分类——topic

② topic下的每一个分区都单独维护一组offset,所以分发到不同分区中的数据都是有序的

消费者消费消息的同时,还维护着消息的offset:一个消费者一个主题的一个分区维护一个offset

④ topic — 逻辑概念      partition — 物理概念

⑤ 每个partition逻辑上对应一个log文件(存储producer生产的数据,追加形式,每条数据都有自己的offset)。

⑥ 消费组中的每个消费组,都会实时记录自己消费到了哪个offset(当出错然后又恢复时,就可从上次的位置继续消费)。

注意:

如果新来的一个消费组,来拉取数据,就从原来的offser+1的位置开始

由于生产的消息会不断追加到 log 文件末尾,当log文件数量过大时,数据定位效率低下,怎么办?

Kafka采取了分片索引机制

● 将每个partition分为多个segment。

● 每个segment对应两个文件 —— ".index"文件和".log"文件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.1 Kafka工作流程及文件存储机制

3.2 Kafka生产者

3.2.1 消息发送流程

Producer发送消息方式:异步发送

两线一变

main线程:()将消息发送给RecordAccumulator。

Sender线程:()不断从RecordAccumulator中拉取消息发送到Kafka broker

RecordAccumulator线程共享变量

相关参数:

batch.size:数据累计到batch.size时,sender才会发送数据

linger.ms:如数据迟迟未达到batch.size,sender等待liger.time之后就会发送数据

 

3.2.2 异步发送API

3.2.3 同步发送API

 

3.2.4 分区策略

1)分区的原因

  ① 方便在集群中扩展

  ② 可提高并发

2)分区的原则

我们需要将producer发送的数据封装成一个ProducerRecord对象

ProducerRecord(topic,partition_num,……)      有partition

  直接发往指定的分区

ProducerRecord(topic,key,value)  无partition,有key

  key的hash值 % topic的partition数    取余得到partition的值  

ProducerRecord(topic,value)  无partition,无key

  采用黏性分区器,会随机选择一个分区,并尽可能一直使用该分区

  待该分区的batch已满或已完成

  kafk再随机一个分区进行使用

 

3.2.5 分区器

 

3.2.6 数据可靠性保证

1)生产者发送数据到 topic partition 的可靠性保证

  ① producer发送数据  →   topic中的partition

  ② topic中的partition发送ack  →   producer

    ③ producer收到ack,进行下一轮的发送,否则重新发送

 

2)Topic partition存储数据的可靠性保证

 

 

 

 

分区分配策略

测试一:
topic  first有三个分区  first0  first1  first2
消费者组 group01    consumer01 — c1      consumer02 — c2     consumer03 — c3  
① 只启动消费者c1                               
分区消费情况   c1 - first2、first1、first0   【一个消费者消费三个分区】

② c1已启动的情况下,再启动 c2          
分区消费情况   c1 - first1、first0       c2 - first2
消费者端的分区分配是什么时候开始分的呢?    消费者组内有新的消费者加入,就会触发

③ c1、c2已启动的情况下,再启动c3     
分区消费情况   c1 - first1   c2 - first2    c3 - first0

③ c1、c2、c3已启动的情况下,再启动c4     
分区消费情况   c1 - first1   c2 - first2    c3 - first0    c4 - 无   【此时碰巧每分配到,一般情况下会打乱,重分配】
 
④ c1、c2、c3、c4已启动的情况下,退出c1    
分区消费情况  c2 - first1    c3 - first0    c4 - first2 
(改)消费者端的分区分配是什么时候开始分的呢?    消费者组内消费者发生变化(增加、减少),就会触发分区重分配

------------------------------------------------------------------------------------------------------------------------------------------------------
测试二: 分区策略使用Range
topic   first有七个分区 first0 first1  first2  first3  irst4  first5  first6 
消费者组 group02    consumer1 — c1      consumer2 — c2     consumer3 — c3  
① 启动c1   
分区消费情况  c1 - first0 first1  first2  first3  irst4  first5  first6

② 已启动c1,再启动c2   
分区消费情况  c1 - first3  first2  first1 first0    c2 -first5  irst4   first6 

③ 已启动c1、c2,再启动c3    
分区消费情况 c1 - first2  first1 first0    c2 -first5  first6   c3 -first3  irst4

④ 已启动c1、c2、c3,关闭c1    【会重新分配】
分区消费情况   c2 -first5  irst4  first6   c3 - first3  first2  first1 first0

------------------------------------------------------------------------------------------------------------------------------------------------------
测试三: 分区策略使用RoundRobin(轮询) 
topic   first有七个分区 first0 first1  first2  first3  irst4  first5  first6 
消费者组 group03    consumer1 — c1      consumer2 — c2     consumer3 — c3  
① 启动c1   
分区消费情况  c1 - first0 first1  first2  first3  irst4  first5  first6

② 已启动c1,再启动c2    【会重新分配】
分区消费情况  c1 - first2  first4  first6 first0    c2 -first3  irst5   first1    

③ 已启动c1、c2,再启动c3    【会重新分配】
分区消费情况 c1 - first3  first6  first0    c2 -first4  first1   c3 -first2  irst5  

④ 已启动c1、c2、c3,关闭c1    【会重新分配】
分区消费情况   c2 -first2  irst4  first6 first0    c3 - first3  first5  first1
 
------------------------------------------------------------------------------------------------------------------------------------------------------
测试三: 分区策略使用Sticky(黏性分区)   减少了消费者退出的时候,分区的切换
topic   first有七个分区 first0 first1  first2  first3  irst4  first5  first6 
消费者组 group03    consumer1 — c1      consumer2 — c2     consumer3 — c3
① 启动c1   
分区消费情况  c1 - first0 first1  first2  first3  irst4  first5  first6

② 已启动c1,再启动c2    
分区消费情况  c1 - first4  first6  first1  first0    c2 -first3  irst2   first5

③ 已启动c1、c2,再启动c3    
分区消费情况 c1 - first6  first1  first0    c2 -first2  first5   c3 -first3  first4  

④ 已启动c1、c2、c3,关闭c1      【会将牺牲的c1的消费分区,分给c2、c3,且c2、c3原来消费的分区不会变动】
分区消费情况   c2 -first2  irst5  first1    c3 - first3  first4  first6   first0

 

posted @ 2021-12-31 14:26  白森  阅读(31)  评论(0编辑  收藏  举报