Kafka之Offset管理标记和寻址、消费模式、参数调优

1、Offset如何标记数据

每个分区的offset都是从1开始标记的
每个分区将数据切分成segment(段),每个段由log和index两份文件组成
假设一个Topic的数据,有三个分区,存了4500条数据:
ruozedata-0 1开始标记…
ruozedata-1 1开始标记…
ruozedata-2 1开始标记…

命名规则:
第一组0开头,存了1000条:
00000000000000000000.index
00000000000000000000.log
第二组,由上一组的最后一条消息的offset来命名,存了2500条:
00000000000000001000.index
00000000000000001000.log
第三组,由第二组的最后一条消息的offset来命名,存了1000条:
00000000000000003500.index
00000000000000003500.log

绝对offset:是关于分区的全局id,比如ruozedata-0分区(3个log文件 全局的id)
相对offset::存储在index文件里,对应其log文件的消息的id,格式是:相对offset-id,对应log的pos位置
index存储:是稀疏存储的, log文件里的每条信息不会都有一个index的,而是挑选的部分index。

举例,假设mysql一张表维护的offset信息:
对于上面提到的概念,结合这个表,就一目了然。

mysql表
globalid  sid message
1         1   
2         2
3         3
4         4
...
1000      1000
------------------
1001       1
1002       2
1003       3
...
1010       10
...
3500       2500
-----------------
3501       1
3502       2 
3503       3
...
4500       1000

2、Offset如何寻址

还是根据上面的例子
假设:寻找offset为1016的消息是什么?
这里的1016是全局的offset,用二分查找法。
第一步,先找到<=1016的最大的segment文件

00000000000000000000.index  # [0-1000)
00000000000000000000.log 

#那么此时知道是落在这个区间,在第二个segment里面,他里面包含的是[1000-3500)的数据条数信息
00000000000000001000.index
00000000000000001000.log 

00000000000000003500.index   #[3500,4500]
00000000000000003500.log    

第二步,1016-1000=16 为index的相对offset,去index找 <=16的最大的相对offset
假设index里面存储的是这样的信息,因为是稀疏存储,不会存所有的index记录。
那么找到的就是: 10,98这一行的信息
在这里插入图片描述
第三步,去对应的log文件找到98位置,按顺序往下读到第16条消息即可,我们要的是第16条的信息,而index只维护了第10条所在位置的信息,所以最优位置只能从第10所在的位置开始读。

#读log文件,98位置,按顺序读到第16条
00000000000000001000.log 

3、消费模式

at most once :最多消费一次 0/1 可能丢数据,但是不重复
at least once:至少消费一次 >=1 不丢数据 但是会重复(实际工作中常用)
exactly once::精准消费一次 1 不丢 也不重复

4、参数调优

配置文件,主要是这三个

[hadoop@vm01 config]$ ll
-rw-r--r--. 1 hadoop hadoop 1221 Nov  9  2018 consumer.properties
-rw-r--r--. 1 hadoop hadoop 1925 Nov  9  2018 producer.properties
-rw-r--r--. 1 hadoop hadoop 6963 Aug  9 09:54 server.properties
#producer
#这意味着领导者将等待完整的同步副本来确认记录。leader是用来读写,另外俩副本用来同步
#这保证了只要至少有一个同步副本仍然存在,记录就不会丢失。这是最有力的保证
acks=all 

#生产者可用于缓冲等待发送到服务器的记录的总内存字节数。
#如果记录发送的速度比发送到服务器的速度快,那么生产者将阻塞max.block。之后,它将抛出异常。
buffer.memory

#生成器生成的所有数据的压缩类型。默认值是none(即没有压缩)
compression.type = snappy

#重试次数
retries=100

#客户机在阻塞之前在单个连接上发送的未确认请求的最大数量。
#注意,如果该设置被设置为大于1且发送失败,则由于重试(即,如果启用重试功能)。
max.in.flight.requests.per.connection=1

#当多个记录被发送到同一个分区时,生产者将尝试将这些记录一起批处理成更少的请求。
#这有助于提高客户机和服务器的性能。此配置以字节为单位控制默认批处理大小。
batch.size

#此设置将限制生产者在单个请求中发送的记录批次的数量,以避免发送巨大的请求。
#这也有效地限制了最大记录批大小。注意,服务器对记录批大小有自己的上限,这可能与此不同。
max.request.size

#客户机等待请求响应的最大时间量
request.timeout.ms
timeout.ms
#Broker/server
advertised.host.name  ?????

#Kafka允许的最大记录批大小
message.max.bytes

#服务器用于处理请求的线程数,可能包括磁盘I/O
num.io.threads

#服务器用于从网络接收请求并向网络发送响应的线程数
num.network.threads

#客户端等待与zookeeper建立连接的最长时间
zookeeper.connection.timeout.ms

#zookeeper会话超时
zookeeper.session.timeout

#consumer: new
#服务器应该为获取请求返回的最大数据量。
fetch.message.max.bytes

#如果为真,使用者的偏移量将在后台定期提交。
auto.commit.enable : false

#当Kafka中没有初始偏移量,或者当前偏移量在服务器上不存在时(例如,因为数据已被删除),该怎么办?
#earliest: 自动重置偏移到最早的偏移
#latest:自动将偏移量重置为最新偏移量
#none: 如果没有为使用者的组找到以前的偏移量,则向使用者抛出异常
#anything else:向使用者抛出异常。
auto.offset.reset
  "auto.offset.reset" -> "latest",
  "enable.auto.commit" -> (false: java.lang.Boolean)

#如果enable.auto.commit设置为true,则使用者偏移量自动提交到Kafka的频率(以毫秒为单位)。
auto.commit.interval.ms
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章