1、 kafka 的 message 包括哪些信息
一个 Kafka 的 Message 由一个固定长度的 header 和一个变长的消息体 body 组成
header 部分由一个字节的 magic(文件格式)和四个字节的 CRC32(用于判断 body 消息体
是否正常)构成。当 magic 的值为 1 的时候,会在 magic 和 crc32 之间多一个字节的数据:
attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果 magic 的值为 0,那
么不存在 attributes 属性
body 是由 N 个字节构成的一个消息体,包含了具体的 key/value 消息
2、怎么查看 kafka 的 offset
0.9 版本以上,可以用最新的 Consumer client 客户端,有 consumer.seekToEnd() / c
onsumer.position() 可以用于得到当前最新的 offset
3、kafka 的数据存在内存还是磁盘
Kafka 最核心的思想是使用磁盘,而不是使用内存,可能所有人都会认为,内存的速度一定
比磁盘快,我也不例外。在看了 Kafka 的设计思想,查阅了相应资料再加上自己的测试后,
发现磁盘的顺序读写速度和内存持平。
而且 Linux 对于磁盘的读写优化也比较多,包括 read-ahead 和 write-behind,磁盘缓存
等。如果在内存做这些操作的时候,一个是 JAVA 对象的内存开销很大,另一个是随着堆内
存数据的增多,JAVA 的 GC 时间会变得很长,使用磁盘操作有以下几个好处:
磁盘缓存由 Linux 系统维护,减少了程序员的不少工作。
磁盘顺序读写速度超过内存随机读写。
JVM 的 GC 效率低,内存占用大。使用磁盘可以避免这一问题。
系统冷启动后,磁盘缓存依然可用。
4、怎么解决 kafka 的数据丢失
producer 端:
宏观上看保证数据的可靠安全性,肯定是依据分区数做好数据备份,设立副本数。
broker 端:
topic 设置多分区,分区自适应所在机器,为了让各分区均匀分布在所在的 broker 中,分
区数要大于 broker 数。
分区是 kafka 进行并行读写的单位,是提升 kafka 速度的关键。
Consumer 端
consumer 端丢失消息的情形比较简单:如果在消息处理完成前就提交了 offset,那么就有可能造成数据的丢失。由于 Kafka consumer 默认是自动提交位移的,所以在后台提交位
移前一定要保证消息被正常处理了,因此不建议采用很重的处理逻辑,如果处理耗时很长,
则建议把逻辑放到另一个线程中去做。为了避免数据丢失,现给出两点建议:
enable.auto.commit=false 关闭自动提交位移
在消息被完整处理之后再手动提交位移
2.kafka数据分区和消费者的关系,kafka的数据offset读取流程,kafka内部如何保证顺序,结合外部组件如何保证消费者的顺序
1、kafka数据分区和消费者的关系:1个partition只能被同组的⼀个consumer消费,同组的consumer则起到均衡效果
2、kafka的数据offset读取流程
1.连接ZK集群,从ZK中拿到对应topic的partition信息和partition的Leader的相关信息
2.连接到对应Leader对应的broker
3.consumer将⾃⼰保存的offset发送给Leader
4.Leader根据offset等信息定位到segment(索引⽂件和⽇志⽂件)
5.根据索引⽂件中的内容,定位到⽇志⽂件中该偏移量对应的开始位置读取相应⻓度的数据并返回给consumer
3、kafka内部如何保证顺序:
kafka只能保证partition内是有序的,但是partition间的有序是没办法的。爱奇艺的搜索架构,是从业务上把需要有序的打到同⼀个partition。
kafka 如何保证消息一致性?
Kafka 判断一个节点是否还活着有那两个条件?
(1)节点必须可以维护和 ZooKeeper 的连接,Zookeeper 通过心跳机制检查每个节点的连接
(2)如果节点是个 follower,他必须能及时的同步 leader 的写操作,延时不能太久
kafka 的 ack 机制
request.required.acks 有三个值 0 1 -1
0:生产者不会等待 broker 的 ack,这个延迟最低但是存储的保证最弱当 server 挂掉的时候就
会丢数据
1:服务端会等待 ack 值 leader 副本确认接收到消息后发送 ack 但是如果 leader 挂掉后他不
确保是否复制完成新 leader 也会导致数据丢失
-1:同样在 1 的基础上 服务端会等所有的 follower 的副本受到数据后才会受到 leader 发出
的 ack,这样数据不会丢失
一个消费者组里它的内部是有序的
消费者组与消费者组之间是无序的
kafaka 生产数据时数据的分组策略
生产者决定数据产生到集群的哪个 partition 中
每一条消息都是以(key,value)格式
Key 是由生产者发送数据传入
所以生产者(key)决定了数据产生到集群的哪个 partition