Kafka高性能相关
1 高性能原因
1.1 高效使用磁盘
(1)顺序写磁盘,顺序写磁盘性能高于随机写内存
(2)Append Only 数据不更新,无记录级的数据删除(只会整个segment删除)
(3)充分利用Page Cache,I/O Scheduler将连续的小块写组装成大块的物理写从而提高性能,将一些写操作重新按顺序排好,从而减少磁盘头的移动时间
(4)充分利用所有空闲内存(非JVM内存),应用层cache也会有对应的page cache与之对应,直接使用page cache可增大可用cache,如使用heap内的cache,会增加GC负担
(5)读操作可直接在page cache内进行。如果进程重启,JVM内的cache会失效,但page cache仍然可用
(6)可通过参数强制flush
(7)支持多Directory
1.2 零拷贝
传统模式下数据从文件传输到网络需要4次数据拷贝,4次上下文切换和2次系统调用。通过NIO的transferTo/transferFrom调用操作系统的sendfile实现零拷贝。总共2次内核数据拷贝,2次上下文切换和1次系统调用,消除了CPU数据拷贝
1.3 批处理和压缩
(1)Producer和Consumer均支持批量处理数据,从而减少了网络传输的开销
(2)Producer可将数据压缩后发送给broker,从而减少网络传输代价。目前支持Snappy,Gzip和LZ4压缩
1.4 Partitio
(1)通过Partition实现了并行处理和水平扩展
(2)Partition是Kafka(包括kafka Stream)并行处理的最小单位
(3)不同Partition可处于不同的Broker,充分利用多机资源
(4)同一Broker上的不同Partition可置于不同的Directory,如果节点上有多个Disk Drive,可将不同的Drive对应的Directory,从而是Kafka充分利用Disk Drive的磁盘优势
1.5 ISR
(1)ISR实现了可用性和一致性的动态平衡
(2)ISR可容忍更多的节点失败。Majority Quorum如果要容忍f个节点失败,至少需要2f+1个节点 ISR如果要容忍f个节点失败,至少需要f+1个节点
(3)如何处理Replica Crach,Leader crash后,ISR中的任何replica皆可竞选称为Leader,如果所有replica都crash,可选择让第一个recover的replica或者第一个在ISR中的replica称为leader
2 kafka性能影响因子
(1)producer :producer和吞吐量成正比
(2)consumer:consumer数据量在没有达到partition个数之前,和消费的吞吐量成正比。
(3)partition:分区格式和生成的吞吐量,在一定范围内,先增长,当达到某一个值之后区域稳定,在上下浮动。
(4)message-size:随着message size的增大,生产者对应的每秒生成的记录数在成下降趋势,区里的数据体积成上升趋势。
(5)replication:副本越大,自然需要同步数据的量就越多,自然kafka的生成的吞吐量就越低。
2.1 kafka脚本查看kafka集群性能
(1)kafka-producer-perf-test.sh:查看kafka生产者的性能。
bin/kafka-producer-perf-test.sh --topic perftest \
--num-records 100000 \ #测试生成多少条记录
--throughput 10000 \ #生产这的吞吐量,约等于messages/sec
--record-size 10 \ #每条消息的大小
--producer.config config/producer.properties
(2)kafka-consumer-perf-test.sh:查看kafka消费者的性能。
bin/kafka-consumer-perf-test.sh --topic perftest \
--broker-list bigdata01:9092,bigdata02:9092,bigdata03:9092 \
--messages 100000 #总共要读取多少条记录
结果参数
start.time=2019-08-06 02:31:23:738 --->开始时间
end.time=2019-08-06 02:31:24:735 --->结束时间
data.consumed.in.MB=0.9534 --->总共消费的数据体积
MB.sec=0.9562 --->每秒钟消费数据体积
data.consumed.in.nMsg=100000 --->总共消费的数据记录数
nMsg.sec=100300.9027 --->每秒钟消费记录数
rebalance.time.ms=47 --->进行rebalance的时间
fetch.time.ms=950 --->抓取这10w条数据总共花费多长时间
fetch.MB.sec=1.0035 --->每秒钟抓取数据体积
fetch.nMsg.sec=105263.1579 --->每秒钟抓取数据记录数