你所不知道的那些知识点--kafka

来源:互联网 发布:哪里买淘宝店铺 编辑:程序博客网 时间:2024/06/05 23:53

你所不知道的消息(Message):
StreamMessage: java数据流信息,用标准流操作来顺序的填充和读取
MapMessage:一个Map类型的消息,名称为string类型,而值为java的基本类型
TextMessage:普通字符串消息,包含一个String
ObjectMessage:对象消息,包含一个可序列化的java对象
BytesMessage:二进制数组消息,包含一个byte[]
XMLMessage:一个XML类型的消息

你所不知道的–kafka集群涉及的几个问题??
1.Segment的概念?
一个分区被分成相同大小的段(Segment),每个Segment由多个索引文件(index)和数据文件(log)组成(segment文件生命周期由服务端配置参数决定)
这里写图片描述

2.查找segment file
00000000000000000000.index表示最开始的文件,起始偏移量(offset)为1
00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1
00000000000000737337.index的起始偏移量为737338=737337 + 1
其他后续文件依次类推。
以起始偏移量命名并排序这些文件,只要根据offset 二分查找文件列表,就可以快速定位到具体文件。当offset=368776时定位到00000000000000368769.index和对应log文件。

这里写图片描述

3.数据是怎么存储到Segment中的? (数据存储机制)
1.Broker接收到数据以后,首先将数据放到操作系统的缓存里(pagecache),pagecache会尽可能多的使用空闲内存
2.使用Sendfile技术尽可能多的减少操作系统和应用程序之间进行重复缓存
3.写入数据时使用顺序写入,写入的速度理论上可以达到600M/s

       *补充:Kafka在磁盘上只做Sequence I/O,由于消息系统读写的特殊性,这并不存在什么问题。关于磁盘I/O的性能,引用一组Kafka官方给出的测试数据(Raid-5,7200rpm):       Sequence I/O: 600MB/s       Random I/O: 100KB/s 所以通过只做Sequence I/O的限制,规避了磁盘访问速度低下对性能可能造成的影响。*

4.Consumer怎么解决负载均衡??
1.获取Consumer消费的起始分区号
2.计算出Consumer要消费的分区数量
3.用起始分区号和分区数来取分区的范围(Hash取模)

5.数据的分发策略
kafka默认调用自己的分区器(DefaultPartitioner),也可以用自定义的分区器,此时要实现Partition接口,重写getPartitioner方法

6.kafka是怎么保证数据不丢失的??
kafka接收到数据后会根据创建Topic的指定的备份数来存储数据,也就是说多备份机制可以保证数据不丢失

你所不知道的kafka如何”抄近路”
1.Kafka重度依赖底层操作系统提供的PageCache功能。当上层有写操作时,操作系统只是将数据写入PageCache,同时标记Page属性为Dirty。

2.当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。同时如果有其他进程申请内存,回收PageCache的代价又很小,所以现代的OS都支持PageCache。

3.使用PageCache功能同时可以避免在JVM内部缓存数据,JVM为我们提供了强大的GC能力,同时也引入了一些问题不适用与Kafka的设计。

***除此之外***

PageCache还只是第一步,Kafka为了进一步的优化性能还采用了Sendfile技术。在解释Sendfile之前,首先介绍一下传统的网络I/O操作流程,大体上分为以下4步:
1.OS 从硬盘把数据读到内核区的PageCache。
2.用户进程把数据从内核区Copy到用户区。
3.然后用户进程再把数据写入到Socket,数据流入内核区的Socket Buffer上。
4.OS 再把数据从Buffer中Copy到网卡的Buffer上,这样完成一次发送。
这里写图片描述

整个过程共经历两次Context Switch,四次System Call。同一份数据在内核Buffer与用户Buffer之间重复拷贝,效率低下。其中2、3两步没有必要,完全可以直接在内核区完成数据拷贝。这也正是Sendfile所解决的问题,经过Sendfile优化后,整个I/O过程就变成了下面这个样子。

优化后
Kafka的设计初衷是尽一切努力在内存中完成数据交换,无论是对外作为一整个消息系统,或是内部同底层操作系统的交互。如果Producer和Consumer之间生产和消费进度上配合得当,完全可以实现数据交换零I/O。这也就是为什么说Kafka使用“硬盘”并没有带来过多性能损失的原因。

阅读全文
2 0
原创粉丝点击