Kafka
- Kafka集群架构
- Kafka分布式集群部署
- Kafka启动与关闭
- Topic管理:创建与列举
- Topic管理:查看与删除
- 生产者及消费者测试
- 在这里插入图片描述
- Kafka集群压力测试
- Kafka API 的应用
- 生产者API:构建KafkaProducer
- 生产者API:生产数据到Kafka
- 消费者API:构建KafkaConsumer
- 消费者API:消费Topic数据
- 生产分区规则
- 自定义开发生产分区器
- 消费者消费过程及问题
- 自动提交问题
- 实现手动提交Topic的Offset
- 手动提交Topic Offset的问题
- 手动提交分区Offset的实现
- 指定消费Topic分区的数据
- 消费分配策略:基本规则及分配策略
- 消费分配策略:RangeAssignor
- 消费分配策略:RoundRobinAssignor
- 在这里插入图片描述
- 消费分配策略:StickyAssignor
- Kafka存储机制:存储结构
- Kafka存储机制:写入过程
- Kafka存储机制:Segment
- Kafka存储机制:读取过程
- Kafka存储机制:index索引设计
- Kafka数据清理规则
- Kafka分区副本概念:AR、ISR、OSR
- Kafka数据同步概念:HW、LEO
- 在这里插入图片描述
- Kafka分区副本Leader选举
- 消息队列的一次性语义
- Kafka保证生产不丢失
- Kafka保证生产不重复
- Kafka保证消费一次性语义
- Kafka集群常用配置
- 可视化工具Kafka Eagle部署及使用
- Kafka数据限流
- Kafka核心:Kafka理论
传统架构面临的问题
-
目标:了解传统架构中存在的问题及解决方案
-
路径
- step1:传统网站的存储架构
- step2:高并发读问题
- step3:高并发写问题
-
实施
- Web1.0版本的网站架构
问题1:读的请求比较多,MySQL无法支撑这么大的读并发,怎么解决?
- Web1.0版本的网站架构
-
引入Redis,作为读缓存,解决高并发的读
-
问题2:如果写的请求也比较多怎么办?
- 引入消息队列:解决高并发写问题
- 引入消息队列:解决高并发写问题
-
-
小结
- 传统的技术架构中:高并发读写的问题
- 高并发读:Redis高并发缓存
- 高并发写:消息队列
消息队列:MQ介绍
-
目标:了解消息队列的功能,应用场景及特点
-
路径
- step1:消息队列是什么?
- step2:什么情况下需要使用消息队列?
- step3:消息队列的优缺点是什么?
-
实施
- 定义
- 官方定义:消息队列是一种异步的服务间通信方式,是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。
- 简单点说:消息队列MQ用于实现两个系统之间或者两个模块之间传递消息数据时,实现数据缓存
- 功能
- 基于队列的方式,实现数据缓存
- 队列的特点:顺序:先进先出
- 基于队列的方式,实现数据缓存
- 应用场景
- 用于所有需要实现实时、高性能、高吞吐、高可靠的消息传递架构中
- 优点
- 实现了架构解耦
- 需求:C也需要A的数据
- 如果不构建消息队列:A =》 B
- 停止A,修改A的代码,添加发送C的代码
- 高耦合度的
- 如果构建了消息队列:A =》 MQ 《= B
- 直接让C从MQ中取即可
- 低耦合度的
- 保证了最终一致性
- 最终可以保证实现最初的需求
- 实现异步,提供传输性能
- A给B和C都发一份数据
- 不做消息队列
- A发送:10s
- B接受:1000s
- C接受:1000s
- 总共:2020s
- 做了消息队列
- A:10s
- B和C并行接受:1000s
- 总共:1010s
- 实现了架构解耦
- 缺点
- 增加了消息队列,架构运维更加复杂
- 必须保证消息队列是高可靠的
- 如果消息队列故障,整个所有系统都瘫痪了
- 数据保证更加复杂,必须保证生产安全和消费安全
- 数据安全
- 数据在传输过程中:不丢失、不重复
- 没有消息队列
- 只要保证A到B安全、A到C的安全
- 引入消息队列
- A到MQ是安全的
- B到MQ是安全的
- C到MQ是安全的
- 数据安全
- 增加了消息队列,架构运维更加复杂
- 定义
-
小结
- 功能:实现两个系统之间传递消息时,基于队列的方式进行数据缓存
- 优点:解耦、异步提高性能
- 缺点:运维更加麻烦
- 必须保证
- 消息队列必须是高可靠系统:分布式系统
- 必须保证所有数据传输的安全:学习核心,不丢失、不重复
消息队列:同步与异步
-
目标:了解什么是同步与异步
-
路径
- step1:什么是同步与异步?
- step2:同步的特点和应用场景?
- step3:异步的特点和应用场景?
-
实施
- 同步的概念
- 流程
- step1:用户提交请求
- step2:后台处理请求
- step3:将处理的结果返回给用户
- 特点:用户看到的结果就是我处理好的结果
- 场景:去银行存钱、转账等,必须看到真正处理的结果才能表示成功,实现立即一致性
- 流程
- 异步的概念
- 流程
- step1:用于提交请求
- step2:后台将请求放入消息队列,等待处理,返回给用户一个临时结果
- step3:用户看到临时的结果,真正的请求在后台等待处理
- 特点:用户看到的结果并不是我们已经处理的结果
- 场景:用户暂时不需要关心真正处理结果的场景下,只要保证这个最终结果是用户想要的结果即可,实现最终一致性
- 流程
- 数据传递的同步与异步
- A给B发送消息:基于UDP协议
- A首先给B发送一条数据
- A不管B有没有收到,继续发送下一条
- 优点:快
- 缺点:数据容易丢失
- 异步过程
- A给B发送消息:基于TCP协议
- A首先给B发送一条数据
- A会等待B告诉A收到了这条消息,A才会发送下一条
- 优点:安全
- 缺点:性能相对差一些
- 同步过程
- A给B发送消息:基于UDP协议
- 同步的概念
-
小结
- 同步:提交和处理是同步操作,立即就能看到结果,立即一致性
- 异步:提交和处理是异步操作,最终得到一个处理的结果,最终一致性
消息队列:点对点模式
-
目标:了解消息队列中消息传递的点对点模式
-
路径
-
实施
- 角色
- 生产者:负责往消息队列中写数据的
- 消息队列:负责缓存传递的数据
- 消费者:负责从消息队列中读取数据的
- 流程
- step1:生产者要往消息队列中写数据
- step2:消费者从消息队列中读数据
- step3:消费者消费成功以后,会返回一个确认给消息队列,消息队列会将消费成功的数据删除
- 角色
-
小结
- 特点:数据只能被一个消费者使用,消费成功以后数据就会被删除,无法实现消费数据的共享
消息队列:订阅发布模式
-
目标:掌握消息队列中消息传递的订阅发布模式
-
路径
-
实施
- 角色
- 生产者
- 消息队列
- 消费者
- Topic:主题,用于划分存储不同业务的数据
- 流程
- step1:生产者往消息队列中生产数据,将数据写入对应的主题中
- step2:消费者可以订阅主题,如果主题中出现新的数据,消费就可以立即消费
- 角色
-
小结
- 特点:一个消费者可以订阅多个主题,一个主题可以被多个消费者订阅
- 消费成功以后,不会立即主动删除数据
- 类似生活中:微信公众号
- 订阅公众号
- 后台发布文章,立即受到推送
- 特点:一个消费者可以订阅多个主题,一个主题可以被多个消费者订阅
vKafka的介绍
-
目标:掌握Kafka的功能、特点及应用场景
-
路径
- Kafka是什么?
- Kafka在大数据中的应用场景是什么?
-
实施
- 官网:kafka.apache.org
- 官网:kafka.apache.org
-
功能
- 分布式消息队列:分布式存储
- 分布式流式计算:分布式计算:KafkaStream
- 这个功能比较鸡肋,不完善,一般不用
- Spark Streaming
- Flink
-
定义
- 分布式的基于订阅发布模式的高吞吐高性能的实时消息队列系统
-
应用场景
- 实时场景
- 实时场景
-
-
-
目前:只要做实时大数据,都必用Kafka,没有其他替代品
- 离线数据仓库:Hive
- 实时数据仓库:Kafka
-
-
-
小结
- Kafka在大数据中专门用于实现实时的数据存储,实现大数据实时计算
Kafka的特点
-
目标:掌握Kafka的特点
-
路径
- 为什么不用Hive?
- 因为Hive底层存储是HDFS
- HDFS适用于离线文件存储
- Kafka用于实时场景下
- 为什么不用Hbase?
- Hbase是一个数据库:做永久性持久化存储
- 必须按照表的形式来存储,有行和列,按列存储
- Hbase的性能问题
- Rowkey、列族、StoreFile、基于JVM堆内存设计的内存结构【GC停顿】
- Hbase是一个数据库:做永久性持久化存储
- 为什么不用Zookeeper?
- Zookeeper的存储只能存储小数据
- 一般用于存储元数据
- 为什么不用Hive?
-
实施
- 高性能:实时的对数据进行读写
- 使用了分布式内存,用到不是堆内存
- 用的是PageCache:操作系统的页缓存机制
- 属于操作系统层次的内存,即使Kafka进程故障,重启Kafka,数据依旧在内存中
- 高并发:分布式并行读写
- 高吞吐:使用分布式磁盘存储,没有使用HDFS
- 顺序写磁盘
- 高可靠:分布式主从架构
- 高安全性
- 内存:Log记录操作
- 磁盘:副本机制
- 高灵活性
- 高性能:实时的对数据进行读写
-
小结
- Kafka是一个高吞吐、高性能、高灵活性、安全性的分布式基于订阅发布模式的消息队列系统
Kafka概念:Producer、Broker、Consumer
-
目标:掌握Kafka中的Producer、Broker、Consumer概念及其功能
-
路径
-
实施
-
Broker:Kafka是一个分布式集群,多台机器构成,每台Kafka的节点就是一个Broker
-
Producer:生产者
- 负责将数据写入Kafka中,工作中一般生成都是数据采集工具
-
Consumer:消费者
- 负责从Kafka中消费数据
-
Consumer Group:Kafka中必须以消费者组的形式来消费数据
- 消费者组到kafka消费数据
- 任何一个消费者必须属于某一个消费者组
- 一个消费者组中可以有多个消费者:多个消费者共同消费数据
- 多个消费者消费的数据是不一样的
- 加在一起是一份完整的数据
-
-
小结
- 生产者 =》 Kafka 集群【多个Broker】 《= 消费者组【消费者】
Kafka概念:Topic、Partition
-
目标:掌握Kafka中的Topic、Partition概念及其功能
-
路径
-
实施
- Topic:数据主题,用于区分不同的数据,对数据进行分类
- 类似于MySQL中会将数据划分到不同的表:不同的数据存储在不同的表中
- Kafka是分布式存储
- Topic就是分布式的概念:一个Topic可以划分多个分区,每个分区存储在不同的Kafka节点上
- Partition:数据分区,用于实现Topic的分布式存储
- 一个Topic可以划分多个分区
- 每个分区存储在不同的Kafka节点上
- 类似于Hbase中的Region
- 例如上图中:Topic名称为T1,T1有三个分区:P0、P1、P2
- Topic:数据主题,用于区分不同的数据,对数据进行分类
-
小结
- Kafka存储
- Broker | Topic
- Partition
Kafka概念:分区副本机制
-
目标:掌握Kafka中的分区副本机制
-
路径
-
实施
- 问题1:Kafka中的每个Topic的每个分区存储在不同的节点上,如果某个节点故障,分区数据如何恢复?
- Kafka选用了副本机制来保证数据的安全性
- Kafka每一个分区都可以由多个副本
- 类似于HDFS的副本机制,一个块构建多个副本
- 注意:Kafka中一个分区的副本个数最多只能等于机器的个数,相同分区的副本不允许放在同一台机器,没有意义
- 问题2:一个分区有多个副本,读写这个分区的数据时候,到底读写哪个分区呢?
- Kafka将一个分区的多个副本,划分为两种角色
- Leader副本:负责对外提供读写
- Follower副本
- 与Leader同步数据
- 如果leader故障,从follower新的leader副本对外提供读写
- 问题1:Kafka中的每个Topic的每个分区存储在不同的节点上,如果某个节点故障,分区数据如何恢复?
-
小结
-
Kafka通过分区副本机制
- 每个分区可以构建多个副本,副本 <= 机器个数
-
Kafka将分区副本划分两种角色
-
leader:对外接受读写请求
-
follower:同步数据、如果leader故障,转换为新的leader
-
-
Kafka概念:Segment
-
目标:掌握Kafka中的Segment概念及其功能
-
路径
-
实施
-
定义:对每个分区的数据进行了更细的划分,先写入的数据会先生成一个文件,存储到一定条件以后,将数据写入另外一个文件,每个文件就叫Segment文件
-
内容:每个Segment对应一对【两个】文件
- xxxxx.log
- 真正存储数据的文件
- xxxxx.index
- 存储文件的索引
- xxxxx.log
-
举例
-
如果分区第一次写入数据,会产生第一个segment
00000000000000000000000.log 00000000000000000000000.index
-
当文件越来越大,存储的数据越来越多,影响读的性能,会再构建一个新的segment,老的segment不再被写入
00000000000000000000000.log 00000000000000000000000.index 00000000000000000199999.log 00000000000000000199999.index ……
- Segment名字就是这个Segment记录的offset的最小值
-
-
-
小结
- Segment就是对分区中是数据再次进行划分,类似于Hbase中Store
- Region:Store
- Partition:Segment
- 不同的是
- Hbase中的Store:按照列族
- Kafka中的Segment:数据的大小或者时间划分
- Segment就是对分区中是数据再次进行划分,类似于Hbase中Store
Kafka概念:Offset
-
目标:掌握Kafka中的Offset概念及其功能
-
路径
-
实施
-
定义:Kafka中所有数据的读取都是按照Offset来读取数据,每条数据的偏移量
-
功能:基于offset来指定数据的顺序,消费时候按照offset顺序来读取
-
生成:生产者往Kafka中写入数据,写入某个分区
- 每个分区单独管理一套Offset【分区】,offset从0开始对每条数据进行编号
- Kafka写入数据也是按照KV来写入数据
-
举例
-
假设一个Topic有3个分区
-
现在往Topic中写入了10条数据
-
part0
offset K value 0 1 hadoop 1 4 hadoop 2 7 flume
-
-
-
part1
offset K value 0 2 hive 1 5 hadoop
-
part2
offset K value 0 3 spark 1 6 hadoop
-
-
-
小结
- Offset用于标记分区中的每条数据,消费者根据上一次消费的offset对分区继续进行消费,保证顺序
- 实现保证数据不丢失不重复
Kafka概念:概念对比总结
-
目标:掌握Kafka中的概念与其他工具的对比,加深理解
-
路径
-
HDFS:分布式文件离线存储系统
-
Hbase:分布式NoSQL实时列存储数据库
-
Kafka:分布式实时消息队列系统
-
实施
概念 HDFS Hbase Kafka 第一层逻辑划分 文件夹/目录 NameSpace - 第二层逻辑划分 文件 Table Topic 存储分区及划分规则 Block Region Partition 分区存储规则 128M 范围 自己指定 分区安全 副本 WAL + HDFS副本 副本:<=机器个数 存储单元 - Store【列族】 Segment 存储位置 磁盘 memstore + StoreFile .log + .index 架构 NameNode + DataNode Hmaster + HregionServer Kafka Contorler + Kafka:Broker HA Zookeeper Zookeeper Zookeeper Kafka集群架构
-
目标:了解Kafka集群架构及角色功能
-
路径
- Kafka集群有哪些角色?
- Kafka每个角色的功能是什么?
- Zookeeper在架构中的作用是什么?
-
实施
- 架构角色
- Kafka
- Zookeeper
- Kafka中的每个角色以及对应的功能
- 分布式主从架构
- 主:Kafka Controller
- 负责管理所有从节点:Topic、分区和副本
- 每次启动集群,会从所有Broker中选举一个Controller,由ZK实现
- 从:Kafka Broker
- 对外提供读写请求
- 其他的Broker监听Controller,如果Controller,会重新从Broker选举一个新的
- ZK的功能
- 辅助选举Active的主节点
- 存储元数据
- 架构角色
-
小结
- kafka是一个主从架构,整体对外提供分布式读写
- ZK主要负责选举Controller和实现元数据存储
Kafka分布式集群部署
-
目标:实现Kafka分布式集群的搭建部署
-
路径
- step1:选择版本
- step2:下载解压安装
- step:3:修改配置文件
-
实施
-
版本的选型
- 0.8.x:老的版本,很多的问题
- 0.10.x +:消息功能上基本没有问题
- 选择:kafka_2.12-2.4.1.tgz
- Kafka:2.4.1
- Scala:2.12,Kafka是由Scala语言开发
-
下载解压安装
-
下载:http://archive.apache.org/dist/kafka/
-
上传到第一台机器
cd /export/software/ rz
-
解压
tar -zxvf kafka_2.12-2.4.1.tgz -C /export/server/ cd /export/server/kafka_2.12-2.4.1/ mkdir logs
- bin:一般用于存放客户端操作命令脚本
- sbin:一般用于存放集群的启动和关闭的命令脚本,如果没有这个命令,脚本放在bin目录中
- conf/etc/config:配置文件目录
- lib:jar包的存放目录
- logs:一般用于存放服务日志
-
-
修改配置
-
切换到配置文件目录
cd /export/server/kafka_2.12-2.4.1/config
-
-
- 修改server.properties
```properties
#21行:唯一的 服务端id
broker.id=0
#60行:指定kafka的日志及数据【segment【.log,.index】】存储的位置
log.dirs=/export/server/kafka_2.12-2.4.1/logs
#123行:指定zookeeper的地址
zookeeper.connect=node1:2181,node2:2181,node3:2181
#在最后添加两个配置,允许删除topic,当前kafkaServer的主机名
delete.topic.enable=true
host.name=node1
```
- 分发
```shell
cd /export/server/
scp -r kafka_2.12-2.4.1 node2:$PWD
scp -r kafka_2.12-2.4.1 node3:$PWD
```
- 第二台:server.properties
```properties
#21行:唯一的 服务端id
broker.id=1
#最后
host.name=node2
```
- 第三台:server.properties
```properties
#21行:唯一的 服务端id
broker.id=2
#最后
host.name=node3
```
- 添加环境变量
```shell
vim /etc/profile
```
```shell
#KAFKA_HOME
export KAFKA_HOME=/export/server/kafka_2.12-2.4.1
export PATH=:$PATH:$KAFKA_HOME/bin
```
```shell
source /etc/profile
```
-
小结
- 按照笔记一步步来,不做过多要求,只要配置含义,实现安装即可
- 解压安装
- 修改配置:server.properties
Kafka启动与关闭
-
目标:掌握kafka集群的启动与关闭命令及脚本封装
-
路径
- step1:如何启动Kafka集群?
- step2:如何关闭Kafka集群?
- step3:如何封装启动及关闭脚本?
-
实施
-
启动Zookeeper
/export/server/zookeeper-3.4.6/bin/start-zk-all.sh
-
启动Kafka
bin/kafka-server-start.sh config/server.properties >>/dev/null 2>&1 & >>/dev/null 2>&1 &:在后台运行
-
关闭Kafka
bin/kafka-server-stop.sh
-
封装Kafka脚本
-
启动脚本
vim /export/server/kafka_2.12-2.4.1/bin/start-kafka.sh
#!/bin/bash KAFKA_HOME=/export/server/kafka_2.12-2.4.1 for number in {1..3} do host=node${number} echo ${host} /usr/bin/ssh ${host} "cd ${KAFKA_HOME};source /etc/profile;export JMX_PORT=9988;${KAFKA_HOME}/bin/kafka-server-start.sh ${KAFKA_HOME}/config/server.properties >>/dev/null 2>&1 &" echo "${host} started" done
chmod u+x /export/server/kafka_2.12-2.4.1/bin/start-kafka.sh
-
关闭脚本
vim /export/server/kafka_2.12-2.4.1/bin/stop-kafka.sh
#!/bin/bash KAFKA_HOME=/export/server/kafka_2.12-2.4.1 for number in {1..3} do host=node${number} echo ${host} /usr/bin/ssh ${host} "cd ${KAFKA_HOME};source /etc/profile;${KAFKA_HOME}/bin/kafka-server-stop.sh" echo "${host} stoped" done
chmod u+x /export/server/kafka_2.12-2.4.1/bin/stop-kafka.sh
-
-
-
小结
- 启动:kafka-server-start.sh
- 关闭:kafka-server-stop.sh
Topic管理:创建与列举
-
目标:掌握Kafka集群中Topic的管理命令,实现创建Topic及列举Topic
-
路径
- step1:Topic脚本的使用
- step2:创建Topic
- step3:列举Topic
-
实施
- Topic管理脚本
- Topic管理脚本
-
-
创建Topic
bin/kafka-topics.sh --create --topic bigdata01 --partitions 3 --replication-factor 2 --bootstrap-server node1:9092,node2:9092,node3:9092
- –create:创建
- –topic :指定操作的Topic的名称
- –partitions:指定分区个数,默认为1
- –replication-factor:副本因子,默认为1
- –bootstrap-server:指定Kafka服务端地址
-
列举Topic
bin/kafka-topics.sh --list -bootstrap-server node1:9092,node2:9092,node3:9092
- –list:表示列举
- –list:表示列举
-
小结
- 创建:create
- 指定分区个数
- 指定副本个数
- 列举:list
- 必选:–bootstrap-server:服务端地址
- 端口:9092
Topic管理:查看与删除
-
目标:掌握Kafka集群中Topic的管理命令,实现查看Topic信息及删除Topic
-
路径
- step1:查看Topic详细信息
- step2:删除Topic
-
实施
-
查看Topic信息
bin/kafka-topics.sh --describe --topic bigdata02 --bootstrap-server node1:9092,node2:9092,node3:9092
Topic: bigdata02 PartitionCount: 2 ReplicationFactor: 3 Configs: segment.bytes=1073741824 Topic: bigdata02 Partition: 0 Leader: 0 Replicas: 0,1,2 Isr: 0,1,2 Topic: bigdata02 Partition: 1 Leader: 2 Replicas: 2,0,1 Isr: 2,0,1
- Partition:分区编号
- Replicas:分区副本所在的Kafka Broker ID
- 每个分区的副本有两种角色
- leader副本
- follower副本
- Leader:leader 副本所在的Kafka节点
- Isr:In-Sync-Replicas:正在同步的副本,可用的副本
- 用于leader故障时,选举新的leader
-
删除Topic
bin/kafka-topics.sh --delete --topic bigdata02 --bootstrap-server node1:9092,node2:9092,node3:9092
-
-
小结
- 查看信息:describe
- 删除:delete
生产者及消费者测试
-
目标:了解命令行如何模拟测试生产者和消费者
-
路径
- step1:构建一个生产者往Topic中生产数据
- 指定Topic
- 指定Kafka集群地址
- step2:构建一个消费者从Topic中消费数据
- 指定Topic
- 指定Kafka集群地址
- step1:构建一个生产者往Topic中生产数据
-
实施
- 命令行提供的脚本
- 命令行提供的脚本
-
Console生产者
bin/kafka-console-producer.sh --topic bigdata01 --broker-list node1:9092,node2:9092,node3:9092
-
Console消费者
bin/kafka-console-consumer.sh --topic bigdata01 --bootstrap-server node1:9092,node2:9092,node3:9092 --from-beginning
-
–from-beginning:从每个分区的最初开始消费,默认从最新的offset进行消费
小结
-
-
只要生产者不断生产,消费就能实时的消费到Topic中的数据
Kafka集群压力测试
-
目标:了解如何实现Kafka集群的吞吐量及压力测试
-
路径
- step1:生产压力测试
- step2:消费压力测试
-
实施
-
创建Topic
bin/kafka-topics.sh --create --topic bigdata --partitions 2 --replication-factor 2 --bootstrap-server node1:9092,node2:9092,node3:9092
-
生产测试
kafka-producer-perf-test.sh --topic bigdata --num-records 5000000 --throughput -1 --record-size 1000 --producer-props bootstrap.servers=node1:9092,node2:9092,node3:9092 acks=1
- –num-records:写入数据的条数
- –throughput:是否做限制,-1表示不限制
- –record-size:每条数据的字节大小
-
-
消费测试
kafka-consumer-perf-test.sh --topic bigdata --broker-list node1:9092,node2:9092,node3:9092 --fetch-size 1048576 --messages 5000000
-
小结
- 工作中一般根据实际的需求来调整参数,测试kafka集群的最高性能,判断是否能满足需求
Kafka API 的应用
-
目标:了解工作中使用Kafka API的场景
-
路径
- step1:工作中使用Kafka的方式
- step2:Kafka API的分类
-
实施
-
命令行使用Kafka
- 一般只用于topic的管理:创建、删除
-
大数据架构中使用Kafka
-
Java API:构建生产者和消费者
-
工作中一般不用自己开发生产者和消费者
-
生产者:数据采集工具
- Flume:Kafka sink
- 配置kafka集群地址
- Topic的名称
- Flume:Kafka sink
-
消费者:实时计算程序
-
SparkStream:KafkaUtil
KafkaUtil.createDirectStream
-
-
这些软件的API已经将Kafka生产者和消费者的API封装了,只要调用即可
-
重点掌握:用到哪些类和方法
-
-
Kafka的API的分类
- High Level API:高级API
- 基于了SimpleAPI做了封装,让用户开发更加方便
- 但是由于封装了底层的API,有很多的东西不能控制,无法控制数据安全
- Simple API:简单API
- 并不简单,最原始的API
- 自定义控制所有消费和生产、保证数据安全
- High Level API:高级API
-
-
小结
- 大数据工作中一般不自己开发Java API:掌握类和方法即可
- 只使用Simple API来实现开发
生产者API:构建KafkaProducer
-
目标:了解如何通过Java API构建生产者
-
路径
- step1:构建集群配置对象
- 指定服务端集群地址
- step2:构建Kafka Porducer对象
- 加载配置
- step1:构建集群配置对象
-
实施
-
构建集群配置对象
//todo:1-构建连接,Kafka生产者对象 //构建配置对象,指定生产者的配置 Properties props = new Properties(); props.put("bootstrap.servers", "node1:9092,node2:9092,node3:9092");//指定集群地址 /** * acks:表示生产者生产数据时,怎么保证数据不丢失,Kafka接受写入数据以后,可以给生产者返回一个ack,表示收到这条数据,生产者发送下一条 * 0:生产者不管Kafka有没有返回ack,都直接发送下一条 * 快、数据容易丢失 * 1:生产者发送数据给Kafka的某个分区,写入leader副本以后,kafka就返回ack,生产者发送下一条 * 相对安全机制,有一定的概率,数据会丢失 * all:生产者发送数据给Kafka的某个分区,写入leader副本并且所有follower同步成功以后,kafka就返回ack,生产者发送下一条 * 最安全,性能较差 */ props.put("acks", "all"); //指定Key的序列化的类 props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); //指定Value的序列化的类 props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
-
构建Kafka Producer加载配置
//构建生产者对象 KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);
-
-
小结
- Properties:构建生产者的配置
- 集群地址
- acks
- 序列化的类
- KafkaProducer:生产者的对象
生产者API:生产数据到Kafka
-
目标:了解如何将数据写入Kafka中
-
路径
- step1:构建ProducerRecord对象
- step2:调用KafkaProducer的send方法将数据写入Kafka
-
实施
-
构建Producer对象
//构建一条数据的对象 //ProducerRecord(String topic, V value) // ProducerRecord<String, String> record = new ProducerRecord<String, String>("bigdata01","itcast"+i); //ProducerRecord(String topic, K key, V value) // ProducerRecord<String, String> record = new ProducerRecord<String, String>("bigdata01",i+"","itcast"+i); //ProducerRecord(String topic, Integer partition, K key, V value) ProducerRecord<String, String> record = new ProducerRecord<String, String>("bigdata01",0,i+"","itcast"+i);
-
调用send方法
//生产数据的数据 producer.send(record);
-
-
小结
- ProducerRecord:表示生产每一条数据
- Topic
- Key
- Value
- 可选:Partition
- KafkaProducer:send:写入数据到Kafka
消费者API:构建KafkaConsumer
-
目标:了解如何通过Java API构建消费者
-
路径
- step1:构建集群配置对象
- step2:构建Kafka Consumer对象
-
实施
-
构建集群配置对象
//todo:1-构建连接,消费者对象 Properties props = new Properties(); props.setProperty("bootstrap.servers", "node1:9092");//服务端地址 props.setProperty("group.id", "test01");//消费者组的id props.setProperty("enable.auto.commit", "true");//是否自动提交offset props.setProperty("auto.commit.interval.ms", "1000");//提交的间隔时间 //指定key和value反序列化的类 props.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
-
构建Kafka Consumer加载配置
KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(props);
-
-
小结
- Properties:配置对象
- KafkaConsumer:消费者对象
消费者API:消费Topic数据
-
目标:了解如何从Kafka中消费数据
-
路径
- step1:消费者订阅Topic
- step2:调用poll方法从Kafka中拉取数据,获取返回值
- step3:从返回值中输出:Topic、Partition、Offset、Key、Value
-
实施
-
消费者订阅Topic
//订阅Topic consumer.subscribe(Arrays.asList("bigdata01"));
-
拉取数据
//消费数据 ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(1));
-
输出数据
//取出每一条数据 for (ConsumerRecord<String, String> record : records) { //获取topic String topic = record.topic(); //获取分区 int partition = record.partition(); //获取offset long offset = record.offset(); //获取Key String key = record.key(); //获取Value String value = record.value(); System.out.println(topic+"\t"+partition+"\t"+offset+"\t"+key+"\t"+value); }
-
-
小结
- KafkaConsumer:subscribe:负责订阅Kafka的Topic
- KafkaConsumer:poll:负责拉取消费数据
- ConsumerRecords:消费到的所有数据的集合
- ConsumerRecord:消费到的每一条数据
- topic:获取Topic
- partition:获取分区
- offset:获取offset
- key:获取key
- value:获取value
生产分区规则
-
目标:掌握Kafka生产者生产数据的分区规则
-
路径
-
问题:为什么生产数据的方式不同,分区的规则就不一样?
- ProducerRecord(Topic,Value) - ProducerRecord(Topic,Key,Value) - ProducerRecord(Topic,Partition,Key,Value)
-
step1:先判断是否指定了分区
- ProducerRecord(Topic,Partition,Key,Value)
-
step2:再判断是否给定了Key
-
指定了Key
- ProducerRecord(Topic,Key,Value)
-
没有指定Key
- ProducerRecord(Topic,Value)
-
-
-
实施
- 如果指定了分区的规则:写入所指定的分区中
- 如果没指定分区
- 如果指定了Key:按照Key的Hash取余分区的个数,来写入对应的分区
- 如果没有指定Key
- 2.x之前:轮询分区
- 优点:数据分配相对均衡
```
Topic part key value
topic 0 1 itcast1
topic 1 2 itcast2
topic 2 3 itcast3
topic 0 4 itcast4
topic 1 5 itcast5
topic 2 6 itcast6
topic 0 7 itcast7
topic 1 8 itcast8
topic 2 9 itcast9
```
- 缺点:性能非常差
- Kafka生产者写入数据:先将数据放入一个缓存中,与分区构建一个连接,发送一个批次的数据
- 第一条数据:先构建0分区的连接,第二条不是0分区的,所以直接构建一个批次,发送第一条
- 第二条数据:先构建1分区的连接,第三条不是1分区的,所以直接构建一个批次,发送第二条
- ……
- 每条数据需要构建一个批次,9条数据,9个批次,每个批次一条数据
- 批次多,每个批次数据量少,性能比较差
- 希望:批次少,每个批次数据量多,性能比较好
- 2.x之后:黏性分区
- 设计:让数据尽量的更加均衡,实现少批次多数据
- 规则
- 第一次:将所有数据随机选择一个分区,全部写入这个分区中,将这次的分区编号放入缓存中
```
bigdata01 1 37 null itcast0
bigdata01 1 38 null itcast1
bigdata01 1 39 null itcast2
bigdata01 1 40 null itcast3
bigdata01 1 41 null itcast4
bigdata01 1 42 null itcast5
bigdata01 1 43 null itcast6
bigdata01 1 44 null itcast7
bigdata01 1 45 null itcast8
bigdata01 1 46 null itcast9
```
- 第二次开始根据缓存中是否有上一次的编号
- 有:直接使用上一次的编号
- 如果没有:重新随机选择一个
-
小结
- Kafka中生产数据的分区规则是什么?
- 是否指定了分区
- 就写入对应的分区
- 如果没有执行分区
- 是否指定了Key:Key的Hash取余分区
- 没有指定Key:黏性分区
- 尽量保证数据均衡前提下,实现少批次多数据
自定义开发生产分区器
-
目标:掌握Kafka自定义开发生产分区器,以随机分区为例
-
路径
- step1:开发一个类实现Partitioner接口
- step2:实现partition方法
- step3:生产者加载分区器
-
实施
-
开发一个随机分区器
package bigdata.itcast.cn.kafka.partition; import org.apache.kafka.clients.producer.Partitioner; import org.apache.kafka.common.Cluster; import java.util.Map; import java.util.Random; /** * @ClassName UserPartition * @Description TODO 自定义分区器,实现随机分区 * @Date 2021/3/31 9:21 * @Create By Frank */ public class UserPartition implements Partitioner { /** * 返回这条数据对应的分区编号 * @param topic:Topic的名 * @param key:key的值 * @param keyBytes:key的字节 * @param value:value的值 * @param valueBytes:value的字节 * @param cluster:集群对象 * @return */ @Override public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) { //获取Topic的分区数 Integer count = cluster.partitionCountForTopic(topic); //构建一个随机对象 Random random = new Random(); //随机得到一个分区编号 int part = random.nextInt(count); return part; } @Override public void close() { //释放资源 } @Override public void configure(Map<String, ?> configs) { //获取配置 } }
-
加载分区器
//指定分区器的类 props.put("partitioner.class","bigdata.itcast.cn.kafka.partition.UserPartition");
-
-
小结
- 如何构建一个自定义分区器
- step1:构建一个类实现Partitioner接口
- step2:实现partition方法:定义分区逻辑
- step3:加载指定分区器即可
消费者消费过程及问题
-
目标:掌握Kafka消费者消费过程及消费问题
-
路径
- step1:消费者是如何消费Topic中的数据的?
- step2:如果消费者故障重启,消费者怎么知道自己上次消费的位置的?
-
实施
-
Kafka中消费者消费数据的规则
-
消费者消费Kafka中的Topic根据Offset进行消费,每次从上一次的位置继续消费
-
第一次消费规则:由属性决定
auto.offset.reset=latest | earliest latest:默认的值,从Topic每个分区的最新的位置开始消费 earliest:从最早的位置开始消费,每个分区的offset为0开始消费
-
第二次消费开始:根据上一次消费的Offset位置+1继续进行消费
-
-
-
-
问题1:消费者如何知道上一次消费的位置是什么?
- 每个消费者都将自己上一次消费的offset记录自己的内存中
-
问题2:如果因为网络资源原因,消费者故障了,重启消费者,原来内存中offset就没有了,消费者怎么知道上一次消费的位置?
-
-
Kafka Offset偏移量管理
- Kafka将每个消费者消费的位置主动记录在一个Topic中:__consumer_offsets
- 如果下次消费者没有给定请求offset,kafka就根据自己记录的offset来提供消费的位置
-
-
提交的规则:根据时间自动提交
props.setProperty("enable.auto.commit", "true");//是否自动提交offset props.setProperty("auto.commit.interval.ms", "1000");//提交的间隔时间
-
-
小结
- 消费者如何消费kafka中的Topic的数据
- 第一次消费:根据属性
- auto.offset.reset:lastest/earliest
- 第二次消费开始:消费者在内存中记录上一次消费的offset + 1 = 这一次要消费的位置
- 第一次消费:根据属性
- 问题:如果消费者故障,重启,不知道上一次的位置怎么办?
- Kafka中记录了每个消费者这一次要消费的位置
- 由消费者定期的自动提交
- 消费者如何消费kafka中的Topic的数据
自动提交问题
-
目标:了解Kafka自动提交Offset存在的问题
-
路径
- step1:自动提交是否会出现数据丢失问题
- step2:自动提交是否会出现数据重复问题
-
实施
-
自动提交的规则
-
根据时间周期来提交下一次要消费的offset
props.setProperty("enable.auto.commit", "true");//是否自动提交offset props.setProperty("auto.commit.interval.ms", "1000");//提交的间隔时间
-
-
数据丢失的情况
- 如果刚消费,还没处理,就达到提交周期,记录了当前 的offset
- 最后处理失败,需要重启,重新消费处理
- Kafka中已经记录消费过了,从上次消费的后面进行消费
-
数据重复的情况
- 如果消费并处理成功,但是没有提交offset,程序故障
- 重启以后,kafka中记录的还是之前的offset,重新又消费一遍
- 数据重复问题
-
-
小结
- 消费是否成功,是根据处理的结果来决定的
- 提交offset是根据时间来决定了
- 需要:根据处理的结果来决定是否提交offset
- 如果消费并处理成功:提交offset
- 如果消费处理失败:不提交offset
实现手动提交Topic的Offset
-
目标:了解Kafka如何实现手动提交Topic的Offset实现
-
路径
- step1:关闭自动提交
- step2:消费完整后手动提交
-
实施
-
关闭自动提交
props.setProperty("enable.auto.commit", "false");//是否自动提交offset // props.setProperty("auto.commit.interval.ms", "1000");//提交的间隔时间
-
手动提交Offset
//处理完成以后,手动提交offset consumer.commitSync();
-
-
小结
- 关闭自动提交
- 根据处理的结果来实现手动提交
- 如果成功以后,再提交
手动提交Topic Offset的问题
-
目标:了解Kafka实现手动提交Topic的Offset的问题
-
路径
- step1:Offset的设计层次
- Offset是什么级别的概念?
- 分区级别的概念
- Offset是什么级别的概念?
- step2:手动提交Topic Offset出现数据重复问题
- step3:解决方案是什么?
- step1:Offset的设计层次
-
实施
-
Offset的设计
- Offset是分区级别,每个分区单独管理一套offset
-
手动提交Topic Offset的过程中会出现数据重复
-
举个栗子
-
一个消费者,消费一个Topic,Topic有三个分区
-
第一次消费
-
part0
0 hadoop 1 hive
-
part1
0 hive 1 spark 2 hue
-
part2
0 spark 1 hadoop
-
-
问题:part0和part1都处理成功,当处理part2时候,程序故障,处理使用
- offset有没有提交?没有提交
- 重启消费者:Kafka中没有消费记录,但是消费者刚刚分区0和分区1已经消费成功了
- 所有分区都重新消费
-
-
-
原因
- Offset是分区级别的
- 提交offset是按照整个Topic级别来提交的
-
解决
- 提交offset的时候,按照分区来提交
- 消费成功一个分区,就提交一个分区的offset
-
-
小结
- 导致问题:数据重复
- 导致原因:offset是分区级别,提交时topic级别,只要有一个分区失败,整个提交失败,实际上部分分区已经处理成功了
手动提交分区Offset的实现
-
目标:掌握Kafka实现手动提交Partition的Offset
-
路径
- step1:消费每个分区的数据
- step2:处理输出每个分区的数据
- step3:手动提交每个分区的Offset
-
实施
-
获取所有数据中的分区
Set<TopicPartition> partitions = records.partitions();
-
从所有数据中取出每个分区的数据,输出,手动提交分区的Offset
//取出每个Partition的数据 for (TopicPartition partition : partitions) { //将这个partition的数据从records中取出 List<ConsumerRecord<String, String>> partRecords = records.records(partition); //遍历这个分区的每一条数据 //取出每一条数据 long offset = 0; for (ConsumerRecord<String, String> record : partRecords) { //获取topic String topic = record.topic(); //获取分区 int part= record.partition(); //获取offset offset = record.offset(); //获取Key String key = record.key(); //获取Value String value = record.value(); System.out.println(topic+"\t"+part+"\t"+offset+"\t"+key+"\t"+value); } //分区数据处理结束,提交分区的offset Map<TopicPartition, OffsetAndMetadata> offsets = Collections.singletonMap(partition,new OffsetAndMetadata(offset+1)); consumer.commitSync(offsets); }
-
观察结果
- 每个分区处理成功,就提交offset
-
-
小结
- 怎么实现基于分区提交offset
- step1:获取所有数据
- step2:获取所有分区
- step3:处理每个分区的数据
- step4:处理成功,提交分区处理的offset + 1
- 注意:工作中:一般不将Offset由Kafka存储,一般自己存储
- 如果处理成功:将offset存储在MySQL或者Zookeeper中
- 如果重启程序:从MySQL或者Zookeeper读取上一次的offset来实现
指定消费Topic分区的数据
-
目标:掌握Kafka如何实现消费指定分区的数据
-
路径
- step1:构建Topic分区对象
- step2:指定消费Topic的分区
- step3:输出消费结果
-
实施
-
构建Topic分区对象
//构建分区对象 TopicPartition part0 = new TopicPartition("bigdata01", 0); TopicPartition part1 = new TopicPartition("bigdata01", 1);
-
指定消费Topic分区
//指定消费某些分区的数据 consumer.assign(Arrays.asList(part0,part1));
-
-
观察结果
-
小结
- 构建Topic的分区对象:TopicPartition
- 消费者指定消费分区:consumer.assign(Collection)
消费分配策略:基本规则及分配策略
-
目标:掌握Kafka消费者组中多个消费者的分配规则及问题
-
路径
- step1:消费者组中消费者分配消费分区的基本规则是什么?
- step2:如果一个消费者组中有多个消费者,消费者组消费多个Topic,每个Topic有多个分区,如何分配?
-
实施
-
基本规则
-
一个分区的数据只能有一个消费者消费
-
不能实现多个消费者消费一个分区的数据
-
原因:每个消费者在逻辑上属于同一个消费者组,但是物理上独立的消费者,无法获取彼此的offset的,不能共同协作的
-
问题:怎么实现一个消费者组中有多个消费者?
-
第一个消费者代码
prop.set("group.id","test01") consumer01 = new KafkaConsumer(prop)
-
第二个消费者代码
prop.set("group.id","test01") consumer02 = new KafkaConsumer(prop)
-
……
-
-
-
一个消费者可以消费多个分区的数据
- 消费者会挨个分区进行消费
-
-
分配策略:决定了多个分区如何分配给多个消费者
-
属性
partition.assignment.strategy = org.apache.kafka.clients.consumer.RangeAssignor
-
策略
-
RangeAssignor:范围分配,默认的分配策略
-
RoundRobinAssignor:轮询分配,常见于Kafka2.0之前的版本
org.apache.kafka.clients.consumer.RoundRobinAssignor
-
StickyAssignor:黏性分配,2.0之后建议使用
org.apache.kafka.clients.consumer.StickyAssignor
-
-
-
-
小结
- 基本规则
- 一个分区只能由一个消费者来消费
- 一个消费者可以消费多个分区
- 分配策略
- 范围分配
- 轮询分配
- 黏性分配
- 基本规则
消费分配策略:RangeAssignor
-
目标:掌握范围分配策略的规则及应用场景
-
路径
- step1:范围分配策略的规则是什么?
- step2:范围分配的优缺点是什么?
-
实施
-
范围分配规则
- Kafka中默认的分配规则
- 每个消费者消费一定范围的分区,尽量的实现将分区均分给不同的消费者,如果不能均分,优先将分区分配给编号小的消费者
- 6个分区:part0 ~ part5
- 2个消费者
- C1:part0 ~ part2
- C2:part3 ~ part5
- 4个消费者
- C1:part0 part1
- C2:part2 part3
- C3:part4
- C4:part5
- 2个消费者
-
举例
-
假设一:三个消费者,消费1个Topic,Topic1有6个分区
消费者 分区 C1 T1【0,1】 C2 T1【2,3】 C3 T1【4,5】
-
-
- 假设二:三个消费者,消费1个Topic,Topic1有7个分区
消费者 | 分区 |
---|---|
C1 | T1【0,1,2】 |
C2 | T1【3,4】 |
C3 | T1【5,6】 |
- 假设三:三个消费者,消费3个Topic,Topic1、Topic2、Topic3各有7个分区
| 消费者 | 分区 |
| :----: | :---------------------------------: |
| C1 | T1【0,1,2】 T2【0,1,2】 T3【0,1,2】 |
| C2 | T1【3,4】 T2【3,4】 T3【3,4】 |
| C3 | T1【5,6】 T2【5,6】 T3【5,6】 |
- 问题:负载不均衡
-
范围分配优点
- 如果Topic的个数比较少,分配会相对比较均衡
-
范围分配缺点
- 如果Topic的个数比较多,而且不能均分,导致负载不均衡问题
-
应用:Topic个数少或者每个Topic都均衡的场景
-
小结
- 规则:每个消费者消费一定范围的分区,尽量做均分,如果不能均分,优先将分区分配给编号小的消费者
- 应用:适合于Topic个数少或者每个Topic都能均分场景
消费分配策略:RoundRobinAssignor
-
目标:掌握轮询分配策略的规则及应用场景
-
路径
- step1:轮询分配的规则是什么?
- step2:轮询规则有什么优缺点?
-
实施
-
轮询分配的规则
-
按照Topic的分区编号,轮询分配给每个消费者
-
如果遇到范围分区的场景,能否均衡
-
三个消费者,消费3个Topic,每个有7个分区
消费者 分区 C1 T1【0,3,6】 T2【2,5】 T3【1,4】 C2 T1【1,4】 T2【0,3,6】 T3【2,5】 C3 T1【2,5】 T2【1,4】 T3【0,3,6】
-
-
-
举例
-
假设一:三个消费者,消费2个Topic,每个Topic3个分区
消费者 分区 C1 T1【0】 T2【0】 C2 T1【1】 T2【1】 C3 T1【2】 T2【2】
-
-
-
假设二:三个消费者,消费3个Topic,第一个Topic1个分区,第二个Topic2个分区,第三个Topic三个分区,消费者1消费Topic1,消费者2消费Topic1,Topic2,消费者3消费Topic1,Topic2,Topic3
T1[0] T2[0,1] T3[0,1,2]
消费者 分区 C1 T1【0】 C2 T2【0】 C3 T2【1】 T3【0】 T3【1】 T3【2】
- 问题:负载不均衡
-
轮询分配的优点
- 如果有多个消费者,消费的Topic都是一样的,实现将所有Topic的所有分区轮询分配给所有消费者,尽量的实现负载的均衡
- 大多数的场景都是这种场景
-
轮询分配的缺点
- 遇到消费者订阅的Topic是不一致的,不同的消费者订阅了不同Topic,只能基于订阅的消费者进行轮询分配,导致整体消费者负载不均衡的
-
应用场景:所有消费者都订阅共同的Topic,能实现让所有Topic的分区轮询分配所有的消费者
-
小结
- 规则:根据订阅关系,将订阅的Topic的分区排序轮询分配给订阅的消费者
- 应用:订阅关系都是一致的
消费分配策略:StickyAssignor
-
目标:掌握黏性分配策略的规则及应用场景
-
路径
- step1:黏性分配的规则是什么?
- step2:黏性分配有什么特点?
-
实施
-
轮询分配的规则
- 类似于轮询分配,尽量的将分区均衡的分配给消费者
-
黏性分配的特点
- 相对的保证的分配的均衡
-
如果某个消费者故障,尽量的避免网络传输
- 尽量保证原来的消费的分区不变,将多出来分区均衡给剩余的消费者
-
举例
-
假设一:三个消费者,消费2个Topic,每个Topic3个分区
消费者 分区 C1 T1【0】 T2【0】 C2 T1【1】 T2【1】 C3 T1【2】 T2【2】 - 效果类似于轮询,比较均衡的分配,但底层实现原理有些不一样
-
假设二:三个消费者,消费3个Topic,第一个Topic1个分区,第二个Topic2个分区,第三个Topic三个分区,消费者1消费Topic1,消费者2消费Topic1,Topic2,消费者3消费Topic1,Topic2,Topic3
消费者 分区 C1 T1【0】 C2 T2【0】 T2【1】 C3 T3【0】 T3【1】 T3【2】
-
-
-
负载均衡的场景
-
假设三:如果假设一中的C3出现故障
-
假设一
消费者 分区 C1 T1【0】 T2【0】 C2 T1【1】 T2【1】 C3 T1【2】 T2【2】 -
轮询:将所有分区重新分配
消费者 分区 C1 T1【0】 T1【2】 T2【1】 C2 T1【1】 T2【0】 T2【2】 -
黏性:直接故障的分区均分给其他的消费者,其他消费者不用改变原来的分区,降低网络IO消耗
消费者 分区 C1 T1【0】 T2【0】 T1【2】 C2 T1【1】 T2【1】 T2【2】
-
-
假设四:如果假设二中的C1出现故障
-
假设二:轮询
消费者 分区 C1 T1【0】 C2 T2【0】 C3 T2【1】 T3【0】 T3【1】 T3【2】 -
轮询负载均衡
消费者 分区 C2 T1【0】 T2【1】 C3 T2【0】T3【0】 T3【1】 T3【2】 -
假设二:黏性
消费者 分区 C1 T1【0】 C2 T2【0】 T2【1】 C3 T3【0】 T3【1】 T3【2】 -
黏性负载均衡
消费者 分区 C2 T2【0】 T2【1】 T1【0】 C3 T3【0】 T3【1】 T3【2】
-
-
-
小结
- 规则:尽量保证所有分配均衡,尽量保证每个消费者如果出现故障,剩余消费者依旧保留自己原来消费的分区
- 特点
- 分配更加均衡
- 如果消费者出现故障,提高性能,避免重新分配,将多余的分区均衡的分配给剩余的消费者
Kafka存储机制:存储结构
-
目标:掌握Kafka的存储结构设计及概念
-
路径
-
实施
- Broker:物理存储节点,用于存储Kafka中每个分区的数据
- Producer:生产者生产数据
- Topic:逻辑存储对象,用于区分不同数据的的存储
- Partition:分布式存储单元,一个Topic可以划分多个分区,每个分区可以分布式存储在不同的Broker节点上
- Segment:分区段,每个分区的数据存储在1个或者多个Segment中,每个Segment由一对文件组成
- Segment命名规则:最小Offset
-
小结
-
Broker【物理进程节点】 | Topic【逻辑对象概念】
-
Partition:逻辑上分布式划分的概念、物理上存储数据的单元
- 分区名称 = Topic名称 + 分区编号
[root@node1 ~]# ll /export/server/kafka_2.12-2.4.1/logs/ 总用量 1212 drwxr-xr-x 2 root root 4096 3月 31 08:59 bigdata-0 drwxr-xr-x 2 root root 215 3月 31 11:23 bigdata01-1 drwxr-xr-x 2 root root 215 3月 31 11:23 bigdata01-2
-
Segment
-rw-r--r-- 1 root root 530080 3月 30 10:48 00000000000000000000.index -rw-r--r-- 1 root root 1073733423 3月 30 10:48 00000000000000000000.log -rw-r--r-- 1 root root 530072 3月 30 10:49 00000000000001060150.index -rw-r--r-- 1 root root 1073734280 3月 30 10:49 00000000000001060150.log -rw-r--r-- 1 root root 189832 3月 31 11:23 00000000000002120301.index -rw-r--r-- 1 root root 384531548 3月 30 10:49 00000000000002120301.log
-
-
Kafka存储机制:写入过程
-
目标:掌握Kafka数据的写入过程
-
路径
- Kafka的数据是如何写入的?
- 为什么Kafka写入速度很快?
-
实施
- step1:生产者生产每一条数据,将数据放入一个batch批次中,如果batch满了或者达到一定的时间,提交写入请求
- step2:Kafka根据分区规则将数据写入分区,获取对应的元数据,将请求提交给leader副本所在的Broker
- 元数据存储:Zookeeper中
- step3:先写入这台Broker的PageCache中
- Kafka也用了内存机制来实现数据的快速的读写:不同于Hbase的内存设计
- Hbase:JVM堆内存
- 所有Java程序都是使用JVM堆内存来实现数据管理
- 缺点
- GC:从内存中清理掉不再需要的数据,导致GC停顿,影响性能
- 如果HRegionServer故障,JVM堆内存中的数据就丢失了,只能通过HLog恢复,性能比较差
- Kafka:操作系统Page Cache
- 选用了操作系统自带的缓存区域:PageCache
- 由操作系统来管理所有内存,即使Kafka Broker故障,数据依旧存在PageCache中
- Hbase:JVM堆内存
- Kafka也用了内存机制来实现数据的快速的读写:不同于Hbase的内存设计
- step4:操作系统的后台的自动将页缓存中的数据SYNC同步到磁盘文件中:最新的Segment的.log中
- 顺序写磁盘:不断将每一条数据追加到.log文件中
- step5:其他的Follower到Leader中同步数据
-
小结
- Kafka的数据是如何写入的?
- step1:生产者构建批次,提交给Kafka集群
- step2:Kafka根据分区规则,检索元数据,将请求转发给Leader副本对应Broker
- step3:先写Broker的PageCache
- step4:后台实现将PageCache中顺序写同步到磁盘中:.log文件
- step5:Follower同步Leader副本的数据
- 为什么Kafka写入速度很快?
- 应用了PageCache的页缓存机制
- 顺序写磁盘的机制
- Kafka的数据是如何写入的?
Kafka存储机制:Segment
-
目标:掌握Segment的设计及命名规则
-
路径
- 为什么要设计Segment?
- Segment是如何实现的?
-
实施
-
设计思想
- 加快查询效率
- 通过将分区的数据根据Offset划分多个比较小的Segment文件
- 在检索数据时,可以根据Offset快速定位数据所在的Segment
- 加载单个Segment文件查询数据,可以提高查询效率
- 减少删除数据IO
- 删除数据时,Kafka以Segment为单位删除某个Segment的数据
- 避免一条一条删除,增加IO负载,性能较差
- 加快查询效率
-
Segment的基本实现
- .log:存储真正的数据
- .index:存储对应的.log文件的索引
-
Segment的划分规则:满足任何一个条件都会划分segment
-
按照时间周期生成
#如果达到7天,重新生成一个新的Segment log.roll.hours = 168
-
按照文件大小生成
#如果一个Segment存储达到1G,就构建一个新的Segment log.segment.bytes = 1073741824
-
-
Segment文件的命名规则
- 以当前文件存储的最小offset来命名的
00000000000000000000.log offset : 0 ~ 2344 00000000000000000000.index 00000000000000002345.log offset : 2345 ~ 6788 00000000000000002345.index 00000000000000006789.log offset : 6789 ~ 00000000000000006789.index
-
-
小结
- 为什么要设计Segment?
- 加快查询效率:将数据划分到多个小文件中,通过offset匹配可以定位某个文件,从小数据量中找到需要的数据
- 提高删除性能:以Segment为单位进行删除,避免以每一条数据进行删除,影响性能
- Segment是如何实现的?
- 组合:一对文件组件
- .log
- .index
- 划分
- 时间:7天
- 大小:1G
- 命名:以这个segment中存储的最小offset来命名
- 组合:一对文件组件
- 为什么要设计Segment?
Kafka存储机制:读取过程
- 目标:掌握Kafka数据的读取过程
- 路径
- Kafka数据是如何被读取的?
- 为什么Kafka读取数据也很快?
- 实施
- step1:消费者根据Topic、Partition、Offset提交给Kafka请求读取数据
- step2:Kafka根据元数据信息,找到对应的这个分区对应的Leader副本
- step3:请求Leader副本所在的Broker,先读PageCache,通过零拷贝机制【Zero Copy】读取PageCache
- step4:如果PageCache中没有,读取Segment文件段,先根据offset找到要读取的那个Segment
- step5:将.log文件对应的.index文件加载到内存中,根据.index中索引的信息找到Offset在.log文件中的最近位置
- 最近位置:index中记录的稀疏索引【不是每一条数据都有索引】
- step6:读取.log,根据索引读取对应Offset的数据
- 小结
- Kafka数据是如何被读取的?
- step1:消费者请求读取数据:Topic+Partition+Offset
- step2:Kafka根据元数据,找到对应分区的leader副本进行检索
- step3:先检索PageCache
- 如果有,就通过零拷贝机制从PageCache中读取数据
- 如果没有,就读取Segment文件段
- step4:先根据Offset找到对应的Segment的一对文件
- step5:先读index,找到offset对应的数据在.log文件中的最近位置
- step6:根据位置,读取.log文件
- 为什么Kafka读取数据也很快?
- 优先基于PageCache内存的读取,使用零拷贝机制
- 按照Offset有序读取每一条
- 构建Segment文件段
- 构建index索引
- Kafka数据是如何被读取的?
Kafka存储机制:index索引设计
-
目标:掌握Kafka的Segment中index的索引设计
-
路径
- .index文件中的索引的内容是什么?
- 查询数据时如何根据索引找到对应offset的数据?
-
实施
-
索引类型
-
全量索引:每一条数据,都对应一条索引
-
稀疏索引:部分数据有索引,有一部分数据是没有索引的
-
优点:减少了索引存储的数据量加快索引的索引的检索效率
-
什么时候生成一条索引?
#.log文件每增加4096字节,在.index中增加一条索引 log.index.interval.bytes=4096
-
Kafka中选择使用了稀疏索引
-
-
-
索引内容
- 两列
- 第一列:这条数据在这个文件中的位置
- 第二列:这条数据在文件中的物理偏移量
是这个文件中的第几条,数据在这个文件中的物理位置 1,0 --表示这个文件中的第一条,在文件中的位置是第0个字节开始 3,497 --表示这个文件中的第三条,在文件中的位置是第497个字节开始
- 两列
-
-
-
这个文件中的第1条数据是这个分区中的第368770条数据,offset = 368769
-
检索数据流程
- step1:先根据offset计算这条offset是这个文件中的第几条
- step2:读取.index索引,根据二分检索,从索引中找到离这条数据最近偏小的位置
- step3:读取.log文件从最近位置读取到要查找的数据
-
举例
-
需求:查找offset = 368772
-
step1:计算是文件中的第几条
368772 - 368769 = 3 + 1 = 4,是这个文件中的第四条数据
-
step2:读取.index索引,找到最近位置
3,497
-
step3:读取.log,从497位置向后读取一条数据,得到offset = 368772的数据
-
-
问题:为什么不直接将offset作为索引的第一列?
- 因为Offset越来越大,导致索引存储越来越大,空间占用越多,检索索引比较就越麻烦
-
-
小结
- .index文件中的索引的内容是什么?
- 第一列:这条数据是这个文件第几条数据
- 第二列:存储这条数据在文件中的物理偏移量
- 查询数据时如何根据索引找到对应offset的数据?
- step1:先根据给定的offset计算这个offset是这个文件的第几条
- step2:读取index索引,找到最近物理位置
- step3:读取.log文件,找到对应的数据
- .index文件中的索引的内容是什么?
Kafka数据清理规则
-
目标:了解Kafka中数据清理的规则
-
路径
- Kafka用于实现实时消息队列的数据缓存,不需要永久性的存储数据,如何将过期数据进行清理?
-
实施
-
属性配置
#开启清理 log.cleaner.enable = true #清理规则 log.cleanup.policy = delete | compact
-
清理规则:delete
-
基于存活时间规则:最常用的方式
log.retention.ms log.retention.minutes log.retention.hours=168/7天
-
基于文件大小规则
#删除文件阈值,如果整个数据文件大小,超过阈值的一个segment大小,将会删除最老的segment,-1表示不使用这种规则 log.retention.bytes = -1
-
基于offset消费规则
-
功能:将明确已经消费的offset的数据删除
-
如何判断已经消费到什么位置
-
step1:编写一个文件offset.json
{ "partitions":[ {"topic": "bigdata", "partition": 0,"offset": 2000}, {"topic": "bigdata", "partition": 1,"offset": 2000} ], "version":1 }
-
step2:指定标记这个位置
kafka-delete-records.sh --bootstrap-server node1:9092,node2:9092,node3:9092 --offset-json-file offset.json
-
-
-
-
清理规则:compact
-
功能:将重复的更新数据的老版本删除,保留新版本,要求每条数据必须要有Key,根据Key来判断是否重复
-
-
小结
- Kafka用于实现实时消息队列的数据缓存,不需要永久性的存储数据,如何将过期数据进行清理?
- delete方案:根据时间定期的清理过期的Segment文件
Kafka分区副本概念:AR、ISR、OSR
-
目标:了解分区副本机制,掌握分区副本中的特殊概念
Topic: bigdata01 PartitionCount: 3 ReplicationFactor: 2 Configs: segment.bytes=1073741824 Topic: bigdata01 Partition: 0 Leader: 2 Replicas: 1,2 Isr: 2,1 Topic: bigdata01 Partition: 1 Leader: 0 Replicas: 0,1 Isr: 1,0 Topic: bigdata01 Partition: 2 Leader: 2 Replicas: 2,0 Isr: 2,0
-
路径
- Kafka中的分区数据如何保证数据安全?
- 什么是AR、ISR、OSR?
-
实施
-
分区副本机制:每个kafka中分区都可以构建多个副本,相同分区的副本存储在不同的节点上
- 为了保证安全和写的性能:划分了副本角色
- leader副本:对外提供读写数据
- follower副本:与Leader同步数据,如果leader故障,选举一个新的leader
-
AR:All - Replicas
-
所有副本:指的是一个分区在所有节点上的副本
每个分区有两个副本 Partition: 0 Replicas: 1,2
-
-
ISR:In - Sync - Replicas
-
可用副本:Leader与所有正在与Leader同步的Follower副本
Partition: 0 Leader: 2 Replicas: 1,2 Isr: 2,1
-
列表中:按照优先级排列【Controller根据副本同步状态以及Broker健康状态】,越靠前越会成为leader
-
-
OSR:Out - Sync - Replicas
-
不可用副本:与Leader副本的同步差距很大,成为一个OSR列表的不可用副本
-
原因:网路故障等外部环境因素,某个副本与Leader副本的数据差异性很大
-
判断是否是一个OSR副本?
-
0.9之前:时间和数据差异
replica.lag.time.max.ms = 10000 可用副本的同步超时时间 replica.lag.max.messages = 4000 可用副本的同步记录差,==该参数在0.9以后被删除==
-
0.9以后:只按照时间来判断
replica.lag.time.max.ms = 10000 可用副本的同步超时时间
-
-
-
-
小结
- Kakfa保证数据安全的机制:副本机制
- AR:所有副本
- ISR:可用副本
- OSR:不可用副本
Kafka数据同步概念:HW、LEO
-
目标:了解Kafka副本同步过程及同步中的概念
-
路径
- 什么是HW、LEO?
- Follower副本如何与Leader进行同步的?
-
实施
- 什么是HW、LEO?
-
HW:当前这个分区所有副本同步的最低位置 + 1,消费者能消费到的最大位置
-
LEO:当前Leader已经写入数据的最新位置 + 1
-
数据写入Leader及同步过程
- step1:数据写入分区的Leader副本
- step1:数据写入分区的Leader副本
-
step2:Follower到Leader副本中同步数据
-
小结
- HW:所有副本都同步的位置,消费者可以消费到的位置
- LEO:leader当前最新的位置
Kafka分区副本Leader选举
-
目标:掌握Kafka的分区副本的Leader选举机制,实现Leader的故障选举测试
-
路径
- 一个分区的Leader副本和Follower副本由谁负责选举?
- 如何实现Leader负载均衡分配?
-
实施
-
Leader的选举
- Controler根据所有节点的负载均衡进行选举每个分区的Leader
-
指定Leader负载均衡分配
-
查看
kafka-topics.sh --describe --topic bigdata01 --zookeeper node1:2181,node2:2181,node3:2181
-
重新分配leader
kafka-leader-election.sh --bootstrap-server node1:9092 --topic bigdata01 --partition=0 --election-type preferred
-
-
-
小结
-
Kafka中Controller的选举由ZK辅助实现
-
Kafka中分区副本的选举:由Controller来实现
-
消息队列的一次性语义
- 目标:了解消息队列的三种一次性语义
- 路径
- 什么是一次性语义?
- 实施
- at-most-once:至多一次
- 会出现数据丢失的问题
- at-least-once:至少一次
- 会出现数据重复的问题
- exactly-once:有且仅有一次
- 只消费处理成功一次
- 所有消息队列的目标
- at-most-once:至多一次
- 小结
- Kafka从理论上可以实现Exactly Once
- 大多数的消息队列一般不能满足Exactly Once就满足at-least-once
Kafka保证生产不丢失
-
目标:掌握Kafka的生产者如何保证生产数据不丢失的机制原理
-
路径
- Kafka如何保证生产者生产的数据不丢失?
-
实施
-
ACK + 重试机制
- 生产者生产数据写入kafka,等待kafka返回ack确认,收到ack,生产者发送下一条
-
选项
- 0:不等待ack,直接发送下一条
- 优点:快
- 缺点:数据易丢失
- 1:生产者将数据写入Kafka,Kafka等待这个分区Leader副本,返回ack,发送下一条
- 优点:性能和安全做了中和的选项
- 缺点:依旧存在一定概率的数据丢失的情况
- all:生产者将数据写入Kafka,Kafka等待这个分区所有副本同步成功,返回ack,发送下一条
- 优点:安全
- 缺点:性能比较差
- 方案:搭配min.insync.replicas来使用
- min.insync.replicas:表示最少同步几个副本就可以返回ack
- 0:不等待ack,直接发送下一条
-
重试机制
retries = 0 发送失败的重试次数
-
-
小结
- Kafka如何保证生产者生产的数据不丢失?
- step1:生产数据时等待Kafka的ack
- step2:返回ack再生产下一条
Kafka保证生产不重复
-
目标:掌握Kafka如何保证生产者生产数据不重复的机制原理
-
路径
- Kafka如何保证生产者生产的数据不重复?
- 什么是幂等性机制?
-
实施
-
数据重复的情况
- step1:生产发送一条数据A给kafka
- step2:Kafka存储数据A,返回Ack给生产者
- step3:如果ack丢失,生产者没有收到ack,超时,生产者认为数据丢失没有写入Kafka
- step4:生产者基于重试机制重新发送这条数据A,Kafka写入数据A,返回Ack
- step5:生产者收到ack,发送下一条B
- 问题:A在Kafka中写入两次,产生数据重复的问题
-
Kafka的解决方案
- 实现:在每条数据中增加一个数据id,下一条数据会比上一条数据id多1,Kafka会根据id进行判断是否写入过了
- 如果没有写入:写入kafka
- 如果已经写入:直接返回ack
- 实现:在每条数据中增加一个数据id,下一条数据会比上一条数据id多1,Kafka会根据id进行判断是否写入过了
-
幂等性机制
f(x) = f(f(x))
- 一个操作被执行多次,结果是一致的
-
-
小结
- Kafka通过幂等性机制在数据中增加数据id,每条数据的数据id都不一致
- Kafka会判断每次要写入的id是否比上一次的id多1,如果多1,就写入,不多1,就直接返回ack
Kafka保证消费一次性语义
-
目标:掌握Kafka如何保证消费者消费数据不丢失不重复
-
路径
- Kafka如何保证消费者消费数据不丢失不重复?
-
实施
- 规则
- 消费者是根据offset来持续消费,只要保证任何场景下消费者都能知道上一次的Offset即可
- 需要:将offset存储在一种可靠外部存储中
- 实现
- step1:第一次消费根据属性进行消费
- step2:消费分区数据,处理分区数据
- step3:处理成功:将处理成功的分区的Offset进行额外的存储
- Kafka:默认存储__consumer_offsets
- 外部:MySQL、Redis、Zookeeper
- step4:如果消费者故障,可以从外部存储读取上一次消费的offset向Kafka进行请求
- 规则
-
小结
-
通过自己手动管理存储Offset来实现
-
消费处理成功
//消费 records = consumer.poll //处理 println //将offset存储在MySQL中 saveToMySQL(partition ,offset){ sql = replace into table value(groupid,topic,part,offset) }
-
程序故障,重启
//消费:根据上一次的offset进行消费 offset = readFromMySQL(groupid,topic) records = consumer.poll(offset)
-
-
Kafka集群常用配置
-
目标:了解Kafka集群、生产者、消费者的常用属性配置
-
路径
- 有哪些常用的集群配置?
- 有哪些常用的生产者配置?
- 有哪些常用的消费者配置?
-
实施
-
集群配置:server.properties
属性 值 含义 broker.id int类型 Kafka服务端的唯一id,用于注册zookeeper,一般一台机器一个 host.name hostname 绑定该broker对应的机器地址 port 端口 Kafka服务端端口:9092 log.dirs 目录 kafka存放数据的路径 zookeeper.connect hostname:2181 zookeeper的地址 zookeeper.session.timeout.ms 6000 zookeeper会话超时时间 zookeeper.connection.timeout.ms 6000 zookeeper客户端连接超时时间 num.partitions 1 分区的个数 default.replication.factor 1 分区的副本数 log.segment.bytes 1073741824 单个log文件的大小,默认1G生成一个 log.index.interval.bytes 4096 log文件每隔多大生成一条index log.roll.hours 168 单个log文件生成的时间规则,默认7天一个log log.cleaner.enable true 开启日志清理 log.cleanup.policy delete,compact 默认为delete,删除过期数据,compact为合并数据 log.retention.minutes 分钟值 segment生成多少分钟后删除 log.retention.hours 小时值 segment生成多少小时后删除【168】,7天 log.retention.ms 毫秒值 segment生成多少毫秒后删除 log.retention.bytes -1 删除文件阈值,如果整个数据文件大小,超过阈值的一个segment大小,将会删除最老的segment,直到小于阈值 log.retention.check.interval.ms 毫秒值【5分钟】 多长时间检查一次是否有数据要标记删除 log.cleaner.delete.retention.ms 毫秒值 segment标记删除后多长时间删除 log.cleaner.backoff.ms 毫秒值 多长时间检查一次是否有数据要删除 log.flush.interval.messages Long.MaxValue 消息的条数达到阈值,将触发flush缓存到磁盘 log.flush.interval.ms Long.MaxValue 隔多长时间将缓存数据写入磁盘 auto.create.topics.enable false 是否允许自动创建topic,不建议开启 delete.topic.enable true 允许删除topic replica.lag.time.max.ms 10000 可用副本的同步超时时间 replica.lag.max.messages 4000 可用副本的同步记录差,该参数在0.9以后被删除 unclean.leader.election.enable true 允许不在ISR中的副本成为leader num.network.threads 3 接受客户端请求的线程数 num.io.threads 8 处理读写硬盘的IO的线程数 background.threads 4 后台处理的线程数,例如清理文件等 -
生产配置:producer.properties
属性 值 含义 bootstrap.servers hostname:9092 KafkaServer端地址 poducer.type sync 同步或者异步发送,0,1,all min.insync.replicas 3 如果为同步,最小成功副本数 buffer.memory 33554432 配置生产者本地发送数据的 缓存大小 compression.type none 配置数据压缩,可配置snappy partitioner.class Partition 指定分区的类 acks 1 指定写入数据的保障方式 request.timeout.ms 10000 等待ack确认的时间,超时发送失败 retries 0 发送失败的重试次数 batch.size 16384 批量发送的大小 metadata.max.age.ms 300000 更新缓存的元数据【topic、分区leader等】 -
消费配置:consumer.properties
属性 值 含义 bootstrap.servers hostname:9092 指定Kafka的server地址 group.id id 消费者组的 名称 consumer.id 自动分配 消费者id auto.offset.reset latest 新的消费者从哪里读取数据latest,earliest auto.commit.enable true 是否自动commit当前的offset auto.commit.interval.ms 1000 自动提交的时间间隔
-
-
小结
- 常用属性了解即可
可视化工具Kafka Eagle部署及使用
-
目标:了解Kafka Eagle的功能、实现Kafka Eagle的安装部署、使用Eagle监控Kafka集群
-
路径
- Kafka Eagle是什么?
- 如何安装部署Kafka Eagle?
- Kafka Eagle如何使用?
-
实施
-
Kafka Eagle的功能
- 用于集成Kafka,实现Kafka集群可视化以及监控报表平台
-
Kafka Eagle的部署启动
-
下载解压:以第三台机器为例
cd /export/software/ rz tar -zxvf kafka-eagle-bin-1.4.6.tar.gz -C /export/server/ cd /export/server/kafka-eagle-bin-1.4.6/ tar -zxf kafka-eagle-web-1.4.6-bin.tar.gz
-
修改配置
-
准备数据库:存储eagle的元数据,在Mysql中创建一个数据库
create database eagle;
-
-
-
-
-
修改配置文件:
cd /export/server/kafka-eagle-bin-1.4.6/kafka-eagle-web-1.4.6/ vim conf/system-config.properties
#配置zookeeper集群的名称 kafka.eagle.zk.cluster.alias=cluster1 #配置zookeeper集群的地址 cluster1.zk.list=node1:2181,node2:2181,node3:2181 #31行左右配置开启统计指标 kafka.eagle.metrics.charts=true #配置连接MySQL的参数,并注释自带的sqlite数据库 kafka.eagle.driver=com.mysql.jdbc.Driver kafka.eagle.url=jdbc:mysql://node3:3306/eagle kafka.eagle.username=root kafka.eagle.password=123456
-
-
配置环境变量
vim /etc/profile #KE_HOME export KE_HOME=/export/server/kafka-eagle-bin-1.4.6/kafka-eagle-web-1.4.6 export PATH=$PATH:$KE_HOME/bin source /etc/profile
-
添加执行权限
cd /export/server/kafka-eagle-bin-1.4.6/kafka-eagle-web-1.4.6 chmod u+x bin/ke.sh
-
启动服务
ke.sh start
-
登陆
网页:node3:8048/ke 用户名:admin 密码:123456
-
-
Kafka Eagle使用
- 监控Kafka集群
- 监控Kafka集群
-
监控Zookeeper集群
-
监控Topic
-
查看数据积压
-
现象:消费跟不上生产速度,导致处理的延迟
-
原因
- 消费者组的并发能力不够
- 消费者处理失败
- 网络故障,导致数据传输较慢
-
解决
- 提高消费者组中消费者的并行度
- 分析处理失败的原因
- 找到网络故障的原因
-
查看监控
-
- 报表
-
小结
-
Kafka中最常用的监控工具
-
用于查看集群信息、管理集群、监控集群
-
Kafka数据限流
-
目标:了解Kafka的数据限流及使用场景
-
路径
- 什么是数据限流?
- 如何实现数据限流?
-
实施
-
Kafka的实时性比较高,会出现以下现象
- 生产的太快,消费速度跟不上
- 生产的太慢,消费的速度太快了
-
限流:限制生产和消费的速度
-
限制生产
bin/kafka-configs.sh --zookeeper node1.itcast.cn:2181 --alter --add-config 'producer_byte_rate=1048576' --entity-type clients --entity-default
- producer_byte_rate=1048576:限制每个批次生产多少字节
-
限制消费
bin/kafka-configs.sh --zookeeper node1.itcast.cn:2181 --alter --add-config 'consumer_byte_rate=1048576' --entity-type clients --entity-default
- consumer_byte_rate=1048576:消费每次消费的字节
-
取消限制
bin/kafka-configs.sh --zookeeper node1.itcast.cn:2181 --alter --delete-config 'producer_byte_rate' --entity-type clients --entity-default bin/kafka-configs.sh --zookeeper node1.itcast.cn:2181 --alter --delete-config 'consumer_byte_rate' --entity-type clients --entity-default
-
-
-
小结
- 了解有该功能即可,一般应用场景较少
Kafka核心:Kafka理论
-
Kafka中分布式架构以及概念
-
Kafka读写流程:为什么很快
-
Kafka怎么保证一次性语义
- 生产不丢失不重复
- 消费不丢失不重复
- 自己管理offset
-
Kafka使用
- Topic的管理:分区、副本
- 生产者:数据采集工具或者分布式计算程序
- 消费者:分布式流式计算程序