目录

  • 大数据之kafka
  • 第一章 kafka概述
  • 1.1 定义
  • 1.2 消息队列
  • 1.2.1 传统消息队列的应用场景
  • 1.2.2 消息队列的两种模式
  • 1.3 kafka基础架构
  • 1.3.1 Broker
  • 1.3.2 Topic
  • 1.3.3 partition
  • 1.3.4 Leader
  • 1.3.5 Follower
  • 1.3.6 replication
  • 第二章 kafka快速入门
  • 2.1 安装部署
  • 2.1.1 集群规划
  • 2.1.2 jar包下载
  • 2.1.3 集群部署
  • 2.2 kafka命令行操作
  • 2.2.1 创建topic
  • 2.2.2 查看topic
  • 2.2.3 删除topic
  • 2.2.4 查看主题详细信息
  • 2.2.5 生产者生产数据
  • 2.2.6 消费者消费数据
  • 2.2.7 修改分区数
  • 第三章 kafka架构深入
  • 3.1 kafka工作流程及文件存储机制
  • 3.1.1 kafka工作流程
  • 3.1.2 kafka文件存储机制
  • 3.2 kafka生产者
  • 3.2.1 分区策略
  • 3.2.2 数据可靠性保证
  • 3.2.3 Exactly Once语义
  • 3.3 kafka消费者
  • 3.3.1 消费方式
  • 3.3.2 分区分配策略
  • 3.3.3 offset的维护
  • 3.3.4 消费者组案例
  • 3.4 kafka高效读写数据
  • 3.5 zookeeper在kafka中的作用
  • 3.6 kafka事务
  • 3.6.1 producer事务
  • 3.6.2 consumer事务
  • 第四章 kafka监控
  • 4.1 kafka Eagle
  • 第五章 总结

大数据之kafka

第一章 kafka概述

1.1 定义

  • kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域

1.2 消息队列

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

  1. 同步处理:

生产者生产数据,直接传给消费者

  1. 异步处理:

生产者生产数据,把数据放在消息队列中,供消费者自行拉取

  • 使用消息队列的好处
  1. 解耦
  • 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束
  1. 可恢复性
  • 系统的一部分组件失效时,不会影响整个系统,消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理
  1. 缓冲
  • 有助于控制和优化数据流经过系统的速度,解决生产消息和消费者消息的处理速度不一致的情况
  1. 灵活性&峰值处理能力
  • 在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见,如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费,使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷请求而完全崩溃
  1. 异步通信
  • 很多时候,用户不想也不需要立刻处理消息,消息队列提供了很多异步处理机制,允许用户把一个消息放入队列中,但并不立即处理它。想向队列中放入多少消息就放多少,然后再需要的时候再去处理它们

1.2.2 消息队列的两种模式

  • 点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
  • 消息生产者生产消息发送到Queue中,然后消息消费者从Queue中取出并且消费消息。消息被消费以后,Queue中不再有存储,所以消费者不可能消费到已经被消费的数据。Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费
  • 发布/订阅模式(一对多,消费者消费数据之后不会清除消息)
  • 消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息,和点对点方式不同,发布到topic的消息会被所有订阅者消费

1.3 kafka基础架构

备注:同一个分区的数据只能被同一个消费者组内的某一个消费者消费

1.3.1 Broker

  • kafka集群包含一个或多个服务器,服务器节点成为broker

1.3.2 Topic

  • 每条发布到kafka集群的消息都有一个类别,这个类别被称为topic
  • 类似于数据库的表名或者ES中的index
  • 物理上不同topic的消息分开存储
  • 逻辑上一个topic的消息虽然保存于一个或多个broker上但用户只需指定消息的topic即可生产或消费数据而不必关心数据存于何处
####在kafka集群中,除了数据文件是存在本机,其他的都存在zookeeper上

1.3.3 partition

  • topic中的数据分割成一个或多个partition
  • 每个topic至少有一个partition,当生产者产生数据的时候,根据分配策略(Hash取模),选择分区,然后将消息追加到指定的分区的末尾(队列)
## partition数据路由规则
1.指定了partition,则直接使用
2.未指定partition,但指定key,通过对key的value进行hash选出一个partition
3.partition和key都未指定,使用轮询选出一个partition
  • 每个消息都会有一个自增的编号
  • 标识顺序
  • 用于标识消息的偏移量,有专门的索引信息
  • 每个partition中的数据使用多个segment文件存储
  • partition中的数据是有序的,不同partition间的数据丢失了数据的顺序
  • 如果topic有多个partition,消费数据时就不能保证数据的顺序,在需要严格保证消息的消费顺序的场景下,需要将partition数目设为1
  • broker存储topic的数据,如果某个topic有N个partition,集群中有N个broker,那么每个broker存储该topic的一个partition。
  • 如果某topic有N个partition,集群中有(N+M)个broker,那么其中有N个broker存储topic的一个partition,剩下的M个broker不存储该topic的partition数据。
  • 如果某topic有N个partition,集群中broker数目少于N个,那么一个broker存储topic的一个或多个partition,在实际生产环境中,尽量避免这种情况发生,容易导致kafka集群数据不均衡

1.3.4 Leader

  • 每个partition有多个副本,其中有且仅有一个作为leader,leader是当前负责数据读写partition
1.producer先从zookeeper的"/borkers/.../state"节点找到该partition的leader
2.producer将消息发送给该leader
3.leader将消息写入本地log
4.followers从leader pull消息,写入本地log后leader发送ACK
5.leader收到所有ISR的replica的ACK后,增加HW(high watermark,最后commit的的offset)并向producer发送ACK

1.3.5 Follower

  • Follower跟随leader,所有写请求都通过leader路由,数据变更会广播给所有follower,follower与leader保持数据同步
  • 如果leader失败,则从follower中选取一个新的leader
  • 当follower挂掉、卡住或同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个follower

1.3.6 replication

  • 数据会存放到topic分区中,但是有可能分区会损坏;分区=partition
  • 我们需要对分区的数据进行备份(备份多少取决于你对数据的重视程度)
  • 我们将分区的数据分为leader(1)和Follower(N)
  • leader负责写入和读取数据
  • follower只负责备份
  • 保证了数据的一致性
  • 备份数设置为N,表示主+备=N(参考HDFS)
##kafka分配replica的算法如下:
1.将所有broker(假设为N)和待分配的partition排序
2.将第i个partition分配到第(i mod n )个broker上
3.将第i个partition的第j个replica分配到第((i+j)mode n)个broker上

第二章 kafka快速入门

2.1 安装部署

2.1.1 集群规划

hadoop102

hadoop103

hadoop104

zookeeper kafka

zookeeper kafka

zookeeper kafka

2.1.2 jar包下载

https://kafka.apache.org/downloads

2.1.3 集群部署

  1. 上传软件包到hadoop102
[xiaoyao@hadoop102 config]$ cd  /opt/src/
[xiaoyao@hadoop102 src]$ ll
总用量 574656
-rw-r--r--. 1 root    root      9623007 6月   7 16:31 apache-zookeeper-3.5.9-bin.tar.gz
-rw-r--r--. 1 root    root    395448622 1月  14 2021 hadoop-3.2.2.tar.gz
-rw-r--r--. 1 xiaoyao xiaoyao 144935989 5月   6 23:54 jdk-8u291-linux-x64.tar.gz
-rw-r--r--. 1 root    root     38424081 6月  17 23:08 kafka_2.10-0.10.2.1.tgz
-rw-rw-r--. 1 xiaoyao xiaoyao      5393 6月  30 22:41 sdimage.xml
  1. 解压软件包
[xiaoyao@hadoop102 src]$ cd  /opt/module/
[xiaoyao@hadoop102 module]$ ll
总用量 4
drwxr-xr-x. 13 xiaoyao xiaoyao 4096 6月  28 00:08 hadoop-3.2.2
drwxr-xr-x.  8 xiaoyao xiaoyao  273 4月   8 03:26 jdk1.8.0_291
drwxr-xr-x.  6 xiaoyao xiaoyao   89 4月  22 2017 kafka
drwxrwxr-x.  6 xiaoyao xiaoyao  134 8月   1 17:29 zookeeper
  1. 修改配置文件
##修改kafka配置文件
[xiaoyao@hadoop102 config]$ pwd
/opt/module/kafka/config
[xiaoyao@hadoop102 config]$ vim  server.properties 

#broker全局唯一编号,不能重复
broker.id=0
#删除topic功能
delete.topic.enable=true
#处理网络请求的线程数量
num.network.threads=3
#处理磁盘IO的线程数量
num.io.threads=8
#发送套接字缓冲区的大小
socket.send.buffer.bytes=102400
#接收套接字缓冲区的大小
socket.receive.buffer.bytes=102400
#请求套接字缓冲区大小
socket.request.max.bytes=104857600
#kafka数据的存放路径
log.dirs=/opt/module/kafka/data
#topic在当前broker上的分区个数
num.partitions=1
#用来恢复和清理data下数据的线程数量
num.recovery.threads.per.data.dir=1
#segment文件保留的最长时间,超时将被删除
log.retention.hours=168
#每个文件的最大空间,默认为1G
log.segment.bytes=1073741824
#配置连接zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181
#配置连接zookeeper超时时间
zookeeper.connection.timeout.ms=6000
#创建目录文件
[xiaoyao@hadoop102 kafka]$ mkdir data  logs

##修改zookeeper配置文件
[xiaoyao@hadoop102 conf]$ mv  zoo_sample.cfg zoo.cfg
#通信心跳时间
tickTime=2000
#Leader和follower初始通信时限
initLimit=10
#Leader和Follower同步通信时限
syncLimit=5
#数据文件目录
dataDir=/opt/module/zookeeper/data
#客户端连接端口
clientPort=2181
#集群信息
server.1=hadoop102:2888:3888
server.2=hadoop103:2888:3888
server.3=hadoop104:2888:3888

#创建目录文件
[xiaoyao@hadoop102 kafka]$ mkdir  /opt/module/zookeeper/data/
[xiaoyao@hadoop102 zookeeper]$ echo  "1"  >>  data/myid
  1. 配置环境变量
[xiaoyao@hadoop102 kafka]$ more  /etc/profile |  grep  "KAFKA_HOME"
export  KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin
  1. 分发安装包
#把hadoop102上的kafka目录文件拷贝到另外两个节点
[xiaoyao@hadoop102 module]$ xsync kafka/
##把hadoop102上的zookeeper目录文件拷贝到另外两个节点
[xiaoyao@hadoop102 module]$ xsync zookeeper/
备注:由于之前配置了分发脚本
  1. 修改另外节点配置信息
##在hadoop103和hadoop104上修改broker.id
#hadoop103
[xiaoyao@hadoop103 kafka]$ grep "broker.id" config/server.properties 
broker.id=1
#hadoop104
[xiaoyao@hadoop104 kafka]$ grep "broker.id" config/server.properties 
broker.id=2

#修改节点上myid
[xiaoyao@hadoop103 zookeeper]$ cat  data/myid 
2
[xiaoyao@hadoop104 zookeeper]$ cat  data/myid 
3
  1. 启动集群
#由于kafka集群依赖于zookeeper工作,须先启动zk
[xiaoyao@hadoop102 bin]$ ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[xiaoyao@hadoop103 bin]$ ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[xiaoyao@hadoop104 bin]$ ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

##启动kafka,三个节点都要启动
#以守护进程启动
[xiaoyao@hadoop102 kafka]$ bin/kafka-server-start.sh -daemon config/server.properties

2.2 kafka命令行操作

2.2.1 创建topic

[xiaoyao@hadoop102 bin]$ ./kafka-topics.sh --create --topic first --zookeeper hadoop102:2181 --partitions 2 --replication-factor 2
Created topic "first".
#备注:创建的主题有两个分区和两个副本,副本数不能超过节点数
#分区的好处:提高读写的并行度,提高主题的负载均衡能力
#副本的好处:数据冗余,容灾,备份,保证数据的一致性!

2.2.2 查看topic

##查看topic,由于是集群,在任意一个节点都能查看
[xiaoyao@hadoop102 bin]$ ./kafka-topics.sh --zookeeper hadoop102:2181   --list
first

2.2.3 删除topic

[xiaoyao@hadoop102 bin]$ ./kafka-topics.sh --zookeeper hadoop102:2181 --delete --topic first
Topic first is marked for deletion.
Note: This will have no impact if delete.topic.enable is not set to true.
#如果配置文件中参数没有设置为true,只是逻辑上标记删除

2.2.4 查看主题详细信息

[xiaoyao@hadoop102 bin]$ ./kafka-topics.sh --zookeeper hadoop102:2181 --topic first --describe
Topic:first	PartitionCount:3	ReplicationFactor:1	Configs:
	Topic: first	Partition: 0	Leader: 2	Replicas: 2	Isr: 2
	Topic: first	Partition: 1	Leader: 0	Replicas: 0	Isr: 0
	Topic: first	Partition: 2	Leader: 1	Replicas: 1	Isr: 1

2.2.5 生产者生产数据

[xiaoyao@hadoop102 bin]$ ./kafka-console-producer.sh --broker-list hadoop102:9092 --topic first

2.2.6 消费者消费数据

#0.9版本以前使用
[xiaoyao@hadoop103 bin]$ ./kafka-console-consumer.sh --topic  first --zookeeper hadoop102:2181
#0.9版本以后使用
[xiaoyao@hadoop104 bin]$ ./kafka-console-consumer.sh --zookeeper hadoop102:2181  --topic first
#从头消费数据
[xiaoyao@hadoop104 bin]$ ./kafka-console-consumer.sh --zookeeper hadoop102:2181  --topic first --from-beginning

2.2.7 修改分区数

[xiaoyao@hadoop102 kafka]$ ./bin/kafka-topics.sh --zookeeper  hadoop102:2181  --alter --topic  first --partitions 4
#只能增加分区,不可减少

第三章 kafka架构深入

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

3.1.1 kafka工作流程

kafka 大数据优化 大数据 卡夫卡_kafka

  • kafka中消息是以topic进行分类的,生产者生产消息,消费者消费消息,都是面向topic的
  • topic是逻辑上的概念,而partition是物理上的概念,每个partition对应一个log文件,该log文件中存储的就是producer生产的数据,生产者生产的数据会被不断追加到该log文件末端,且每条数据都有自己的offset,消费者组中的每个消费者,都会实时记录自己消费到了哪个offset,以便出错恢复时,从上次的位置继续消费

3.1.2 kafka文件存储机制

kafka 大数据优化 大数据 卡夫卡_数据_02

  • 由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据定位
    效率低下,Kafka 采取了分片和索引机制,将每个 partition 分为多个 segment。每个 segment
    对应两个文件——“.index”文件和“.log”文件。这些文件位于一个文件夹下,该文件夹的命名
    规则为:topic 名称+分区序号。例如,first 这个 topic 有三个分区,则其对应的文件夹为 first-
    0,first-1,first-2。
00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log
  • index 和 log 文件以当前 segment 的第一条消息的 offset 命名。下图为 index 文件和 log
    文件的结构示意图。
  • “.index”文件存储大量的索引信息,“.log”文件存储大量的数据索引文件中的元
    数据指向对应数据文件中 message 的物理偏移地址。

3.2 kafka生产者

3.2.1 分区策略

  1. 分区的原因
  • 方便在集群中扩展,每个partition可以通过调整以适应它所在的机器,而一个topic又可以有多个partition组成,因此整个集群就可以适应任意大小的数据了
  • 可以提高并发,因为可以以partition为单位读写了
  1. 分区的原则
  • 指明partition的情况下,直接将指明的值直接作为partition值
  • 没有指明partition值但有key的情况下,将key的hash值与topic的partition数进行取余得到partition值
  • 既没有partition值又没有key值的情况下,第一次调用时随机生成一个整数(后面每次调用在这个整数上自增),将这个值与topic可用的partition总数取余得到partition值,也就是常说的轮询算法

3.2.2 数据可靠性保证

  • 副本数据同步策略
  • ISR机制
  • ack应答机制
  • 故障处理:HW、LEO
  1. 副本数据同步策略

两种副本同步策略(kafka选择第二种)

方案

优点

缺点

半数以上完成同步,就发送ack

延迟低

选举新的leader时,容忍n台节点的故障,需要2n+1个副本

全部同步完成,才发送ack

选举新的leader时,容忍n台节点的故障,需要n+1个副本

延迟高

  • kakfa选择第二种同步策略,原因如下:
  • 为了容忍n台节点的故障,第一种方案需要2n+1个副本,而第二种方案只需要n+1个副本,而Kafka的每个分区都有大量的数据,第一种方案会造成大量数据的冗余。
  • 虽然第二种方案的网络延迟会比较高,但网络延迟对Kafka的影响较小。
  1. ISR
  • 为了防止Kafka在选择第二种数据同步策略时,因为某一个follower故障导致leader一直等下去,Leader维护了一个动态的in-sync replica set (ISR)。
  • ISR:同步副本,和leader保持同步的follower集合,当ISR中的 follower完成数据的同步之后,leader就会给生产者发送ack。
  • 如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定(默认:10s)。
  • 如果Leader发生故障,就会从ISR中选举新的leader。
  1. ack应答机制
  • 为保证生产者发送的数据,能可靠的发送到指定的topic,topic的每个partition收到的数据后,都需要向生产者发送ack(确认收到),如果生产者收到ack,就会进行下一轮的发送,否则从新发送数据

kafka为用户提供了三种可靠性级别(acks参数)

  • acks=0
    producer不等待broker的ack,broker一接收到还没有写入磁盘就已经返回。
    当broker故障时,有可能丢失数据。
  • acks=1
    producer等待broker的ack,partition的leader落盘成功后返回ack。
    如果在follower同步成功之前leader故障,那么将会丢失数据。
  • acks=-1(all)
    producer等待broker的ack,partition的leader和follower(ISR中的所有follower)全部落盘成功后才返回ack。
    如果在follower同步完成后,broker发送ack之前leader发生故障,此时kafka从ISR中重新选举一个leader,生产者没有收到ack重新发送一份到新leader上,则造成数据重复。
    如果ISR中只剩一个leader时,此时leader发生故障,可能会造成数据丢失。
    如果一个follower故障,该节点被踢出ISR,只要ISR中所有节点都同步即可返回ack,不影响。
  1. 故障处理
  • LEO:每个副本的最后一个Offset
  • HW:所有副本中最小的LEO
    (1)follower故障
    follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了。

(2)leader故障

leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的 follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。

注意:这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。(是否丢数据是acks保证)

3.2.3 Exactly Once语义

  • 将服务器的ACK级别设置为-1,可以保证生产者到server之间不会丢失数据,即At Least Once语义,相对的,将服务器ACK级别设置为0,可以保证生产者每条消息只会被发送一次,即At Most Once语义
  • At Least Once可以保证数据不丢失,但是不能保证数据不重复;相对的,At Most Once可以保证数据不重复,但不能保证数据不丢失,但是对于一些非常重要的信息,比如说交易数据,下游数据消费者要求数据既不重复也不丢失,即Exactly Once语义,在0.11版本以前的kafka,对此是无能为力的,只能保证数据不丢失,再在下游消费者对数据做全局去重,对于多个下游应用的情况,每个都需要单独做全局去重,这就对性能造成极大影响。
  • 0.11版本后的kafka,引入了这一重大特性:幂等性,所谓的幂等性就是指生产者无论向server发送多少次重复数据,server只会持久化一条,幂等性结合At Least Once语义,就构成了kafka的Exactly Once语义
  • At Least Once + 幂等性 = EXactly Once
  • 要开启幂等性,只需要将生产者的参数中enable.idompotence设置为true,kafka的幂等性实现其实就是将原来下游需要做的去重放在了数据上游,开启幂等性的生产者在初始化的时候会被分配一个PID,发往同一partition的消息会附带Sequence Number。而broker端会对<PID,Partition,SeqNumber>做缓存,当具有相同主键的消息提交时,broker只会持久化一条
  • 但是PID重启就会变化,同时不同的partition也具有不同主键,所以幂等性无法保证跨分区会话的Exactly Once

3.3 kafka消费者

3.3.1 消费方式

  • consumer采用pull(拉)模式从broker读取数据
  • push(推)模式很难适应速率不同的消费者,因为消息发送速率是由broker决定的。它的目标是尽可能以最快速度传递消息,但是这样容易造成consumer来不及处理消息,典型的表现就是拒绝服务和网络堵塞,而pull模式可以根据consumer的消费能力以适当的速率消费消息
  • pull模式的不足之处是,如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据,针对这一点,kafka消费者在消费数据时会传入一个时长参数timeout,如果当前没有数据可供消费,consumer会等待一段时间之后再返回,这段时长是timeout

3.3.2 分区分配策略

  • kafka有两种分配策略
  • RoundRobin(轮询),面向对象为组
  • Range(范围),面向对象为主体

3.3.3 offset的维护

kafka 大数据优化 大数据 卡夫卡_数据_03

  • 由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置继续消费,所以consumer需要实时记录自己消费到了哪个offset,以便故障恢复后继续消费
  • 根据消费者组、主题、分区来决定offset

3.3.4 消费者组案例

  1. 需求:测试同一个消费者组中的消费者,同一时刻只能有一个消费者消费
  2. 案例实操
  • 在Hadoop102、hadoop103上修改group.id为任意组名
[xiaoyao@hadoop102 config]$ vim  /opt/module/kafka/config/consumer.properties 
group.id=xiaoyao
  • 在hadoop102、hadoop103上分别启动消费者
[xiaoyao@hadoop102 kafka]$ bin/kafka-console-consumer.sh --zookeeper  hadoop102:2181  --topic first  --consumer.config  config/consumer.properties 
[xiaoyao@hadoop103 kafka]$ bin/kafka-console-consumer.sh --zookeeper  hadoop102:2181  --topic first  --consumer.config  config/consumer.properties
  • 在hadoop104上启动生产者
[xiaoyao@hadoop104 kafka]$ bin/kafka-console-producer.sh --broker-list  hadoop102:9092 --topic  first
  • 查看hadoop102和hadoop103的接收者
  • 同一时刻只有一个消费者能够接收到数据

3.4 kafka高效读写数据

  1. 顺序写磁盘
  • kafka的producer生产数据,要写入到log文件中,写的过程是一直追加到文件末端,为顺序写,官网有数据表明,同样的磁盘,顺序写能到600M/s,而随机写只有100k/s,这与磁盘的机械结构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间
  1. 零复制技术

3.5 zookeeper在kafka中的作用

  • kafka集群中有一个broker会被选举为controller,负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作
  • controller的管理工作都是依赖于zookeeper的

3.6 kafka事务

  • kafka从0.11版本开始引入了事务支持,事务可以保证kafka在Exactly Once语义的基础上,生产和消费可以跨分区会话,要么全部成功,要么全部失败

3.6.1 producer事务

  • 为了实现跨分区跨会话的事务,需要引入一个全局唯一的Transaction ID,并将producer获得的PID和Transaction ID绑定,这样当producer重启后就可以通过正在进行的Transaction ID获得原来的ID
  • 为了管理Transaction,kafka引入了一个新的组件Transaction Coordinator,producer就是通过和Transaction Coordinator交互获得Transaction ID对应的任务状态,Transaction Coordinator还负责将事务所有写入kafka的一个内部topic,这样即使整个服务重启,由于事务状态得到保存,进行中的事务状态可以得到恢复,从而继续运行

3.6.2 consumer事务

  • 上述事务机制主要是从producer方面考虑,对于consumer而言,事务的保证就会相对较弱,尤其无法保证commit的信息被精确消费,这是由于consumer可以通过offset访问任意消息,而且不同的segmentFile生命周期不同,同一事务的消息可能会出现重启后被删除的情况

第四章 kafka监控

4.1 kafka Eagle

  1. 修改kafka启动命令
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
    export KAFKA_HEAP_OPTS="-server -Xms1G -Xmx2G -XX:PermSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=8 -XX:ConcGCThreads=5 -XX:InitiatingHeapOccupancyPercent=70"
    export JMX_PORT="9999"
fi
#修改后需要分发到其他节点
  1. 上传压缩包到集群/opt/src目录,并解压
[xiaoyao@hadoop102 src]$ ls
apache-zookeeper-3.5.9-bin.tar.gz  hadoop-3.2.2.tar.gz  jdk-8u291-linux-x64.tar.gz  kafka_2.10-0.10.2.1.tgz  kafka-eagle-bin-2.0.1.tar.gz  sdimage.xml
[xiaoyao@hadoop102 module]$ ll
总用量 4
drwxr-xr-x. 13 xiaoyao xiaoyao 4096 6月  28 00:08 hadoop-3.2.2
drwxr-xr-x.  8 xiaoyao xiaoyao  273 4月   8 03:26 jdk1.8.0_291
drwxr-xr-x.  8 xiaoyao xiaoyao  113 8月   1 18:05 kafka
drwxrwxr-x.  3 xiaoyao xiaoyao   65 8月  16 16:09 kafka-eagle
drwxrwxr-x.  8 xiaoyao xiaoyao  158 8月   1 18:29 zookeeper
  1. 配置环境变量
export KE_HOME=/opt/module/kafka-eagle
export PATH=$PATH:$KE_HOME/bin
  1. 修改配置文件
kafka.eagle.zk.cluster.alias=cluster1
cluster1.zk.list=hadoop102:2181,hadoop103:2181,hadoop104:2181
cluster1.zk.acl.enable=false
cluster1.zk.acl.schema=digest
cluster1.zk.acl.username=test
cluster1.zk.acl.password=test123
cluster1.kafka.eagle.broker.size=20
kafka.zk.limit.size=25
kafka.eagle.webui.port=8048
cluster1.kafka.eagle.offset.storage=kafka  #根据kafka版本配置

kafka.eagle.metrics.charts=true
kafka.eagle.metrics.retain=15
kafka.eagle.sql.topic.records.max=5000
kafka.eagle.sql.fix.error=true
kafka.eagle.topic.token=keadmin

kafka.eagle.driver=com.mysql.jdbc.Driver
kafka.eagle.url=jdbc:mysql://192.168.10.102:3306/ke?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
kafka.eagle.username=root
kafka.eagle.password=123456
  1. 启动服务
#启动之前先启动zk和kafka
[xiaoyao@hadoop102 kafka-eagle]$ ke.sh start
* Kafka Eagle Service has started success.
* Welcome, Now you can visit 'http://192.168.10.102:8048'
* Account:admin ,Password:123456

第五章 总结

  1. kafka消息数据积压,kafka消费能力不足怎么处理
  • 如果是kafka消费能力不足,则可以考虑增加topic的分区数,并且同时提升消费者组的消费者数量,消费者数=分区数(两者缺一不可)
  • 如果是下游的数据处理不及时:提高每批次拉取的数量,批次拉取数据过少(拉取数据/处理时间<生产速度),使处理的数据小于生产的数据,也会造成数据积压
  1. Leader 总是 -1,怎么破?
  • 在生产环境中,你一定碰到过“某个主题分区不能工作了”的情形。使用命令行查看状态的 话,会发现 Leader 是 -1,于是,你使用各种命令都无济于事,最后只能用“重启大 法”。
  • 但是,有没有什么办法,可以不重启集群,就能解决此事呢?
  • 删除 ZooKeeper 节点 /controller,触发 Controller 重选举。 Controller 重选举能够为所有主题分区重刷分区状态,可以有效解决因不一致导致的 Leader 不可用问题