1.kafka高性能的特点及条件
kafka是一个高吞吐量分布式消息系统,并且提供了持久化。其高性能的有两个重要特点:(1)利用了磁盘连续读写性能远远高于随机读写的特点;(2)并发,将一个topic拆分多个partition。
要充分发挥kafka的性能,就需要满足这两个条件。linkedin的测试,就把这两个方面发挥到极致(参考http://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines)
(1)磁盘的连续性
要充分利用磁盘连续读写高性能的特点,就意味着要减少操作系统对磁盘的重新调度。kakfa内部的实现非常巧妙:
生产: 网络 —> pagecache(内存) —>磁盘
消费: 磁盘 —> 网络 (使用sendfile将磁盘数据直接拷贝到网卡发送缓冲区)
这样的设计使得,写磁盘的机会仅仅是pagecache需要flush到磁盘的时候;这样保证了大多数时候磁盘可以连续地读取,而且直 接复制到网卡,避免消费影响到生产(写入内存)。另外,使用文件系统pagecache而不是自建缓存,还利用pagecache对于 sendfile来说是透明的优势,也就是在没有消息堆积时,数据流动实际时pagecahe直接到网卡,减少磁盘io又保证及时消费。
(2)并发,将topic拆分多个partition
kafka读写的单位是partition,因此,将一个topic拆分为多个partition可以提高吞吐量。但是,这里有个前提,就是不同partition需 要位于不同的磁盘(可以在同一个机器)。如果多个partition位于同一个磁盘,那么意味着有多个进程同时对一个磁盘的多个文 件进行读写,使得操作系统会对磁盘读写进行频繁调度,也就是破坏了磁盘读写的连续性。
在linkedlin的测试中,每台机器就加载了6个磁盘,并且不做raid,就是为了充分利用多磁盘并发读写,又保证每个磁盘连续读写 的特性。
具体配置上,是将不同磁盘的多个目录配置到broker的log.dirs,例如
log.dirs=/disk1/kafka-logs,/disk2/kafka-logs,/disk3/kafka-logs
kafka会在新建partition的时候,将新partition分布在partition最少的目录上,因此,一般不能将同一个磁盘的多个目录设置到log.dirs
2.kafka在虚拟机环境的优化
kafka高性能很大程度依赖于磁盘(文件系统)的连续读写,而在虚拟机环境中,文件系统一些不同的特点,因此做好这些优化很有必要。
(1)虚拟文件系统的特点
通常,虚拟机不会直接使用物理磁盘(尽管可以)。多个物理磁盘或者raid阵列被宿主系统虚拟成一个大的磁盘,再分配各个虚拟机。对于虚拟文件系统来说,有2个特点比较重要
写优先。大多数虚拟文件系统为了保证磁盘数据的更新,都会一定程度保证写优先
非连续。对于可变大小的虚拟磁盘,通常再需要空间的时候再进行实际分配,造成逻辑上连续的文件,物理存储并不一定连续
高性能。为了支持多个虚拟机同时运行,合理的情况下配置的整体磁盘性能会比较高
不稳定。由于多个虚拟机同时运行的互相影响,可能会出现资源争夺导致的不稳定
(2)kafka在虚拟机环境的优化
首先是,多磁盘的并发的问题。不管怎么说,虚拟机环境至少剥夺了单个kafka同时使用多个磁盘的优势。也就意味着,在在同一个虚拟机,同一个topic,最好只有一个partition;当然,不同topic之间partition如果同时生产-消费也会互相影响,但不一定会同时在高峰(同个topic一定)。构建较大集群(在不同物理机)仍然能够保持并发优势。
其次,写优先和不稳定也是需要考虑问题。如果多个topic同时写入,或者其他虚拟机抢占资源,可能会导致消费缓慢。因此,监控就显得特别重要,对于消费过慢的partition 暂停写入。由于pagecache默认会使用所有可用内存,增加内存可以减少flush到磁盘的次数,使得读取(消费)更加顺利。
另外,为了保证读写连续性,kafka自身及其他服务不要和log.dir共享磁盘。在美团虚拟机上,可以考虑将kafka 安装在系统磁盘, 数据盘(/opt)完全用于日志存储。
总结一下,kafka在虚拟机环境的优化有三点:
第一,组建较大集群,并保证同一个topic的不同partition位于不同虚拟机(所以在不同的磁盘)
第二,监控,对于消费过慢的partition(所在的broker),暂停写入(生产),等待消费
第三,将kafka安装在系统盘,数据盘(/opt)完全用于消息存储。数据盘上不安装其他服务
不得不提的是,以上结论在美团办公云(读取200mb/s +)上测试有明显的表现;。但是,良好的配置可以提升稳定性,比如出现多个topic同时达到高峰,或者出现别的虚 拟机抢占资源的时候,通常更不容易出现故障。
(3) 内存相关设置
现在线上 默认的jvm内存堆分配较大(比如8g内存给jvm堆6g),导致系统其他可用内存比较小。pagecache是linux内核的低优先级缓存,在内存空间富裕的情况下才能获得较大的空间。并且kafka不自建缓存,堆空间需求也比较小。因此建议保留物理内存的1/2以上给系统,以便保证pagecache的分配。
关于jvm内存参数设置请参考:jvm调优总结
引用自-洪进栋wiki