Kafka

Kafka

传统架构面临的问题

  • 目标了解传统架构中存在的问题及解决方案

  • 路径

    • step1:传统网站的存储架构
    • step2:高并发读问题
    • step3:高并发写问题
  • 实施

    • Web1.0版本的网站架构
      在这里插入图片描述
      问题1:读的请求比较多,MySQL无法支撑这么大的读并发,怎么解决?
  • 引入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才会发送下一条
        • 优点:安全
        • 缺点:性能相对差一些
        • 同步过程
  • 小结

    • 同步:提交和处理是同步操作,立即就能看到结果,立即一致性
    • 异步:提交和处理是异步操作,最终得到一个处理的结果,最终一致性

消息队列:点对点模式

  • 目标了解消息队列中消息传递的点对点模式

  • 路径
    在这里插入图片描述

  • 实施

    • 角色
      • 生产者:负责往消息队列中写数据的
      • 消息队列:负责缓存传递的数据
      • 消费者:负责从消息队列中读取数据的
    • 流程
      • step1:生产者要往消息队列中写数据
      • step2:消费者从消息队列中读数据
      • step3:消费者消费成功以后,会返回一个确认给消息队列,消息队列会将消费成功的数据删除
  • 小结

    • 特点:数据只能被一个消费者使用,消费成功以后数据就会被删除,无法实现消费数据的共享

消息队列:订阅发布模式

  • 目标掌握消息队列中消息传递的订阅发布模式

  • 路径
    在这里插入图片描述

  • 实施

    • 角色
      • 生产者
      • 消息队列
      • 消费者
      • Topic:主题,用于划分存储不同业务的数据
    • 流程
      • step1:生产者往消息队列中生产数据,将数据写入对应的主题中
      • step2:消费者可以订阅主题,如果主题中出现新的数据,消费就可以立即消费
  • 小结

    • 特点:一个消费者可以订阅多个主题,一个主题可以被多个消费者订阅
      • 消费成功以后,不会立即主动删除数据
    • 类似生活中:微信公众号
      • 订阅公众号
      • 后台发布文章,立即受到推送

vKafka的介绍

  • 目标掌握Kafka的功能、特点及应用场景

  • 路径

    • Kafka是什么?
    • Kafka在大数据中的应用场景是什么?
  • 实施

    • 官网: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停顿】
    • 为什么不用Zookeeper?
      • Zookeeper的存储只能存储小数据
      • 一般用于存储元数据
  • 实施

    • 高性能:实时的对数据进行读写
      • 使用了分布式内存,用到不是堆内存
      • 用的是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
  • 小结

    • Kafka存储
    • Broker | Topic
      • Partition

Kafka概念:分区副本机制

  • 目标掌握Kafka中的分区副本机制

  • 路径
    在这里插入图片描述

  • 实施

    • 问题1:Kafka中的每个Topic的每个分区存储在不同的节点上,如果某个节点故障,分区数据如何恢复?
      • Kafka选用了副本机制来保证数据的安全性
      • Kafka每一个分区都可以由多个副本
        • 类似于HDFS的副本机制,一个块构建多个副本
      • 注意:Kafka中一个分区的副本个数最多只能等于机器的个数,相同分区的副本不允许放在同一台机器,没有意义
    • 问题2:一个分区有多个副本,读写这个分区的数据时候,到底读写哪个分区呢?
      • Kafka将一个分区的多个副本,划分为两种角色
      • Leader副本:负责对外提供读写
      • Follower副本
        • 与Leader同步数据
        • 如果leader故障,从follower新的leader副本对外提供读写
  • 小结

    • Kafka通过分区副本机制

      • 每个分区可以构建多个副本,副本 <= 机器个数
    • Kafka将分区副本划分两种角色

      • leader:对外接受读写请求

      • follower:同步数据、如果leader故障,转换为新的leader

Kafka概念:Segment

  • 目标掌握Kafka中的Segment概念及其功能

  • 路径

    在这里插入图片描述

  • 实施

    • 定义:对每个分区的数据进行了更细的划分,先写入的数据会先生成一个文件,存储到一定条件以后,将数据写入另外一个文件,每个文件就叫Segment文件

    • 内容:每个Segment对应一对【两个】文件

      • xxxxx.log
        • 真正存储数据的文件
      • xxxxx.index
        • 存储文件的索引
    • 举例

      • 如果分区第一次写入数据,会产生第一个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:数据的大小或者时间划分

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:分布式实时消息队列系统

  • 实施

    概念HDFSHbaseKafka
    第一层逻辑划分文件夹/目录NameSpace-
    第二层逻辑划分文件TableTopic
    存储分区及划分规则BlockRegionPartition
    分区存储规则128M范围自己指定
    分区安全副本WAL + HDFS副本副本:<=机器个数
    存储单元-Store【列族】Segment
    存储位置磁盘memstore + StoreFile.log + .index
    架构NameNode + DataNodeHmaster + HregionServerKafka Contorler + Kafka:Broker
    HAZookeeperZookeeperZookeeper

    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

    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:表示列举
      在这里插入图片描述
  • 小结

    • 创建: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集群地址
  • 实施

    • 命令行提供的脚本
      在这里插入图片描述
  • 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:每条数据的字节大小

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jbe40JxO-1617841119278)(20210330_分布式实时消息队列Kafka(二).assets/image-20210330104918488.png)]

  • 消费测试

    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的名称
      • 消费者:实时计算程序

        • SparkStream:KafkaUtil

          KafkaUtil.createDirectStream
          
      • 这些软件的API已经将Kafka生产者和消费者的API封装了,只要调用即可

      • 重点掌握:用到哪些类和方法

    • Kafka的API的分类

      • High Level API:高级API
        • 基于了SimpleAPI做了封装,让用户开发更加方便
        • 但是由于封装了底层的API,有很多的东西不能控制,无法控制数据安全
      • Simple API:简单API
        • 并不简单,最原始的API
        • 自定义控制所有消费和生产、保证数据安全
  • 小结

    • 大数据工作中一般不自己开发Java API:掌握类和方法即可
    • 只使用Simple API来实现开发

生产者API:构建KafkaProducer

  • 目标了解如何通过Java API构建生产者

  • 路径

    • step1:构建集群配置对象
      • 指定服务端集群地址
    • step2:构建Kafka Porducer对象
      • 加载配置
  • 实施

    • 构建集群配置对象

       //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自动提交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是什么级别的概念?
        • 分区级别的概念
    • step2:手动提交Topic Offset出现数据重复问题
    • step3:解决方案是什么?
  • 实施

    • 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
    • 举例

      • 假设一:三个消费者,消费1个Topic,Topic1有6个分区

        消费者分区
        C1T1【0,1】
        C2T1【2,3】
        C3T1【4,5】

在这里插入图片描述

  • 假设二:三个消费者,消费1个Topic,Topic1有7个分区
消费者分区
C1T1【0,1,2】
C2T1【3,4】
C3T1【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个分区

          消费者分区
          C1T1【0,3,6】 T2【2,5】 T3【1,4】
          C2T1【1,4】 T2【0,3,6】 T3【2,5】
          C3T1【2,5】 T2【1,4】 T3【0,3,6】
    • 举例

      • 假设一:三个消费者,消费2个Topic,每个Topic3个分区

        消费者分区
        C1T1【0】 T2【0】
        C2T1【1】 T2【1】
        C3T1【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]
    
    消费者分区
    C1T1【0】
    C2T2【0】
    C3T2【1】 T3【0】 T3【1】 T3【2】

在这里插入图片描述


  - 问题:负载不均衡
  • 轮询分配的优点

    • 如果有多个消费者,消费的Topic都是一样的,实现将所有Topic的所有分区轮询分配给所有消费者,尽量的实现负载的均衡
    • 大多数的场景都是这种场景
  • 轮询分配的缺点

    • 遇到消费者订阅的Topic是不一致的,不同的消费者订阅了不同Topic,只能基于订阅的消费者进行轮询分配,导致整体消费者负载不均衡的
  • 应用场景:所有消费者都订阅共同的Topic,能实现让所有Topic的分区轮询分配所有的消费者

  • 小结

    • 规则:根据订阅关系,将订阅的Topic的分区排序轮询分配给订阅的消费者
    • 应用:订阅关系都是一致的

消费分配策略:StickyAssignor

  • 目标掌握黏性分配策略的规则及应用场景

  • 路径

    • step1:黏性分配的规则是什么?
    • step2:黏性分配有什么特点?
  • 实施

    • 轮询分配的规则

      • 类似于轮询分配,尽量的将分区均衡的分配给消费者
    • 黏性分配的特点

      • 相对的保证的分配的均衡
    • 如果某个消费者故障,尽量的避免网络传输

      • 尽量保证原来的消费的分区不变,将多出来分区均衡给剩余的消费者
    • 举例

      • 假设一:三个消费者,消费2个Topic,每个Topic3个分区

        消费者分区
        C1T1【0】 T2【0】
        C2T1【1】 T2【1】
        C3T1【2】 T2【2】
        • 效果类似于轮询,比较均衡的分配,但底层实现原理有些不一样
      • 假设二:三个消费者,消费3个Topic,第一个Topic1个分区,第二个Topic2个分区,第三个Topic三个分区,消费者1消费Topic1,消费者2消费Topic1,Topic2,消费者3消费Topic1,Topic2,Topic3

        消费者分区
        C1T1【0】
        C2T2【0】 T2【1】
        C3T3【0】 T3【1】 T3【2】

在这里插入图片描述

  • 负载均衡的场景

    • 假设三:如果假设一中的C3出现故障

      • 假设一

        消费者分区
        C1T1【0】 T2【0】
        C2T1【1】 T2【1】
        C3T1【2】 T2【2】
      • 轮询:将所有分区重新分配

        消费者分区
        C1T1【0】 T1【2】 T2【1】
        C2T1【1】 T2【0】 T2【2】
      • 黏性:直接故障的分区均分给其他的消费者,其他消费者不用改变原来的分区,降低网络IO消耗

        消费者分区
        C1T1【0】 T2【0】 T1【2】
        C2T1【1】 T2【1】 T2【2】
    • 假设四:如果假设二中的C1出现故障

      • 假设二:轮询

        消费者分区
        C1T1【0】
        C2T2【0】
        C3T2【1】 T3【0】 T3【1】 T3【2】
      • 轮询负载均衡

        消费者分区
        C2T1【0】 T2【1】
        C3T2【0】T3【0】 T3【1】 T3【2】
      • 假设二:黏性

        消费者分区
        C1T1【0】
        C2T2【0】 T2【1】
        C3T3【0】 T3【1】 T3【2】
      • 黏性负载均衡

        消费者分区
        C2T2【0】 T2【1】 T1【0】
        C3T3【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中
    • 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存储机制: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来命名

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存储机制: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文件,找到对应的数据

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副本
      在这里插入图片描述
  • 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
        

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IcjaTW18-1617842044811)(20210402_分布式实时消息队列Kafka(五).assets/image-20210402091307091.png)]


  • 小结

    • Kafka中Controller的选举由ZK辅助实现

    • Kafka中分区副本的选举:由Controller来实现

消息队列的一次性语义

  • 目标了解消息队列的三种一次性语义
  • 路径
    • 什么是一次性语义?
  • 实施
    • at-most-once:至多一次
      • 会出现数据丢失的问题
    • at-least-once:至少一次
      • 会出现数据重复的问题
    • exactly-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
    • 重试机制

      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的解决方案

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yy1mBq2U-1617842068092)(20210402_分布式实时消息队列Kafka(五).assets/image-20210331155610879.png)]

      • 实现:在每条数据中增加一个数据id,下一条数据会比上一条数据id多1,Kafka会根据id进行判断是否写入过了
        • 如果没有写入:写入kafka
        • 如果已经写入:直接返回ack
    • 幂等性机制

      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.idint类型Kafka服务端的唯一id,用于注册zookeeper,一般一台机器一个
      host.namehostname绑定该broker对应的机器地址
      port端口Kafka服务端端口:9092
      log.dirs目录kafka存放数据的路径
      zookeeper.connecthostname:2181zookeeper的地址
      zookeeper.session.timeout.ms6000zookeeper会话超时时间
      zookeeper.connection.timeout.ms6000zookeeper客户端连接超时时间
      num.partitions1分区的个数
      default.replication.factor1分区的副本数
      log.segment.bytes1073741824单个log文件的大小,默认1G生成一个
      log.index.interval.bytes4096log文件每隔多大生成一条index
      log.roll.hours168单个log文件生成的时间规则,默认7天一个log
      log.cleaner.enabletrue开启日志清理
      log.cleanup.policydelete,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.messagesLong.MaxValue消息的条数达到阈值,将触发flush缓存到磁盘
      log.flush.interval.msLong.MaxValue隔多长时间将缓存数据写入磁盘
      auto.create.topics.enablefalse是否允许自动创建topic,不建议开启
      delete.topic.enabletrue允许删除topic
      replica.lag.time.max.ms10000可用副本的同步超时时间
      replica.lag.max.messages4000可用副本的同步记录差,该参数在0.9以后被删除
      unclean.leader.election.enabletrue允许不在ISR中的副本成为leader
      num.network.threads3接受客户端请求的线程数
      num.io.threads8处理读写硬盘的IO的线程数
      background.threads4后台处理的线程数,例如清理文件等
    • 生产配置:producer.properties

      属性含义
      bootstrap.servershostname:9092KafkaServer端地址
      poducer.typesync同步或者异步发送,0,1,all
      min.insync.replicas3如果为同步,最小成功副本数
      buffer.memory33554432配置生产者本地发送数据的 缓存大小
      compression.typenone配置数据压缩,可配置snappy
      partitioner.classPartition指定分区的类
      acks1指定写入数据的保障方式
      request.timeout.ms10000等待ack确认的时间,超时发送失败
      retries0发送失败的重试次数
      batch.size16384批量发送的大小
      metadata.max.age.ms300000更新缓存的元数据【topic、分区leader等】
    • 消费配置:consumer.properties

      属性含义
      bootstrap.servershostname:9092指定Kafka的server地址
      group.idid消费者组的 名称
      consumer.id自动分配消费者id
      auto.offset.resetlatest新的消费者从哪里读取数据latest,earliest
      auto.commit.enabletrue是否自动commit当前的offset
      auto.commit.interval.ms1000自动提交的时间间隔
  • 小结

    • 常用属性了解即可

可视化工具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
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZIl23Nt-1617842175147)(20210402_分布式实时消息队列Kafka(五).assets/image-20210402102447211.png)]

  • Kafka Eagle使用

    • 监控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的管理:分区、副本
    • 生产者:数据采集工具或者分布式计算程序
    • 消费者:分布式流式计算程序
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值