1. 高效实用磁盘
- 顺序写磁盘:顺序写磁盘,性能非常刚甚至能与随机写内存相媲美。
- Append Only:数据不更新,无记录级别的数据删除,(只会整个segment删除)
- I/O Scheduler 将连续的小块写组装成大块的物理写从而提高性能
- I/O Scheduler 会尝试将一些写操作重新按顺序排好,从而减少磁盘头的移动时间
- 充分利用 Page Cache( Page Cache 看下面介绍)
- 充分利用所有空闲内存(非JVM内存)
- 应用层cache也会有对应 page cache 与之对应,直接使用 page cache 来增大可用 cache,如果使用 heap 内的 cache 会增加GC 负担
- 读操作可直接在 page cache 内进行,如果进程重启,JVM内 的 cache 会失效,但是page cache仍然可用
- 写磁盘时不会强制flush,如果想强制flush可使用下面参数,但是不建议这么做
- log.flush.interval.messages=10000
- log.flush.interval.ms=1000
- 数据支持多目录存储,可使用多个Drive
Page cache(页面缓存)
Page cache 也叫页缓冲或文件缓冲,是由好几个磁盘块构成,大小通常为4k,在64位系统上为8k,构成的几个磁盘块在物理磁盘上不一定连续,文件的组织单位为一页, 也就是一个page cache大小,文件读取是由外存上不连续的几个磁盘块,到buffer cache,然后组成page cache,然后供给应用程序。
Page cache在linux读写文件时,它用于缓存文件的逻辑内容,从而加快对磁盘上映像和数据的访问。具体说是加速对文件内容的访问,buffer cache缓存文件的具体内容——物理磁盘上的磁盘块,这是加速对磁盘的访问。
Linux系统中的Page cache和Buffer cache
2. CPU数据零拷贝
传统模式下,数据从文件传输到网络需要4次数据拷贝、4次上下文切换和两次系统调用
file.read(fileDesc,buffer,len);
socket.send(socket,buffer,len);
但是kafka使用的处理这方便采用的方案是通过 NIO 的 transferTo / transferFrom 调用操作系统的 sendfile 实现零拷贝。总共发生2次内核数据拷贝、2次上下文切换和一次系统调用,消除了CPU数据拷贝。
public void transferTo(long position,long count,WritableByteChannel target)
3. 批处理和数据压缩
- Producer和Consumer均支持批量处理数据,从而减少了网络传输的开销。
- Producer可将数据压缩后发送给broker,从而减少网络传输代价,目前支持的压缩算法有:Snappy、Gzip、LZ4
- 还可以在数组发送之前采用压缩算法对数据进行压缩
4. partition
- 通过partition实现了并行处理和水平扩展,topic 可以有多个partition,消费组中每个消费者都可以消费一个partition,这样并行消费增加数据处理速度。
- partition是Kafka并行处理的最小单位
- 不同partition 可处于不同broker上,充分利用资源
- 同一broker上的不同partition可处于不同的目录下,如果节点上有多个Disk Drive,可将不同的Drive对应不同的路径下,从而使kafka充分利用多Disk Drive的磁盘优势
5. ISR
ISR实现了可用性和一致性的动态平衡
- replica.lag.time.max=10000
- replica.lag.max.message=4000 # 0.9及以后版本后被移除
ISR 可容忍更多的节点失败
- majority Quorum如果要容忍f个节点失败,则集群至少需要2f+1个节点
- ISR如果要容忍f个节点失败,则集群至少要有f+1个节点
如何处理 Replica Crash
- Leader Crash 后,ISR中的任意副本都可以竞选成为Leader
- 如果所有的replica都Crash,可选择让第一个恢复的副本或者第一个在ISR中的副本成为Leader
- unclean.leader.election.enable=true