Kafka 线上环境部署需要考虑的因素
【操作系统选型】
【硬件规划】
【容量规划】
操作系统选型
目前部署最多的三类操作系统为:Linux,OS X和Windows, 其中部署在Linux的最多,Linux也是推荐的操作系统。下面是两个主要原因:
- IO模型的使用
对于IO模型,Linux下有5种主流的模型:阻塞IO
,非阻塞IO
,多路复用IO
,信号驱动IO
,异步IO
. 每一种IO模型都有典型的使用场景,如Socket的阻塞模型和非阻塞模型对应于前两种,Linux中的select函数属于IO多路复用模型,至于第五种很少有UNIX和类UNIX支持,Windows的IOCP(IO Completion Port)属于第五种。至于Linux的epoll模型,可以看作兼具第三种和第四种模型的特性。
通常情况下我们认为epoll比select模型更高级,毕竟epoll取消了轮询机制,取而代之的是回调机制callback。相当于底层连接Socket过多时,可以避免很多无意义的CPU时间浪费。
在Kafka的client底层网络设计中,新版本采用了Java NIO的Selector机制,这种机制在Linux的实现就是epoll,但在windows上,Java NIO的selector底层使用的是select模型而非IOCP实现,,只有Java NIO2才使用IOCP实现,因此在这一点上,Linux比Windows上运行kafka更加高效。
- 数据网络传输效率
对于数据网络传输,大部分操作都是使用Java的FileChannel.transferTo方法实现。Linux平台上该方法会调用底层的sendfile系统调用,采用了Linux提供的零拷贝技术(zero copy)。
零拷贝技术:在内核驱动程序处理IO数据时,它可以减少甚至规避不必要的CPU数据拷贝操作,避免数据在操作系统内核地址空间
和用户应用程序地址空间
的缓冲区进行重复拷贝,从而获得更好的性能。
Linux提供的nmap,sendfile和splice等系统调用实现了这样的技术。
然而对于Windows而言,虽然它也提供了TransmitFile函数来支持零拷贝技术,但是直到Java 8u60版本,windows才正式让FileChannel的transferTo调用该函数。详情见bug地址:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8064407
因此对于windows上没有更新到java8的业务系统,就可能无法享受到零拷贝技术带来的高效数据传输。
磁盘规划
对于HDD机械硬盘和SSD固态硬盘的选择,Kafka因为其顺序读写磁盘的原因让SSD随机读写快的优势不那么明显了。 所以选择更廉价的HDD也能很好的胜任存储任务。
对于JBOD(一堆普通磁盘)和RAID(磁盘阵列)的选择,由于Kafka底层架构本身提供的副本机制提供冗余和高可靠性,让RAID本身提供的数据冗余和负载均衡的优势就没那么明显了。
推荐用户为每个Broker配置多个日志路径,每个路径都独立挂载在不同的磁盘上,,使得多块物理磁盘磁头同事执行物理IO写操作,可以极大的加快kafka消息生产的速度。
磁盘容量规划
假设场景:每天1亿条消息 ,每条消息保存两个副本,每条消息保留一周时间,平均每条消息大小1K,我们需要多少磁盘空间?
1亿 21KB/1000/1000 = 200GB
预留10%用于存储其他数据,210GB
保存一周 : 210GB * 7 = 1.5TB
消息压缩:压缩比为0,5 : 需要0.75TB空间
综上所述,容量规划需要考虑的因素有:
- 新增消息数
- 消息存留时间
- 平均消息大小
- 副本数
- 是否启用压缩
内存规划
Kafka会将消息写入操作系统的页缓存(page cahce),然后操作系统再写入磁盘。而且Consumer读消息的时候,也会先从页缓存尝试查找,如果直接命中则完全不用执行物理IO,提高消息的消费性能。
不管是缓冲已发送的消息还是待读取的消息,操作系统都要先开辟一块内存区域用于存放接收的Kafka消息,这块内存区域大小对于Kafka性能提升尤为关键。
Kafka对于Java堆内存的需求确不是很多,因为Kafka中的消息通常属于不会存活很久的对象,很快会被GC掉。
一般情况下,堆内存不会超过6G
,文件系统的页缓存大小可以设置为10-14GB
另外,页缓存大小应该比单个日志段大小略大
,这样待消费的数据很大概率都会存在页缓存中。
CPU规划
Kafka不是计算密集型系统,所以追求多核为非高时钟频率。 机器拥有16个CPU比该机器的CPU频率高达4GHZ更加重要。
注意:当Client启用消息压缩,需要消耗更多的CPU资源
带宽规划
对于像Kafka这样的在网络间传输大量数据的分布式数据管道
,一个快速且稳定的网络是Kafka集群搭建的前提条件。
例如 网卡为1Gb/s, 需要设定阀值70%,也就是710Mb/s,这是高峰情况,一般情况为1/3,约为240Mb/s
如果要在一小时传输1TB业务消息,每秒需要传输292MB数据,也就是2336Mb的数据,那么至少需要2336/240=10台Broker机器,副本数为2,则翻一倍为20台Broker。
- 尽量使用高速网络
- 根据网卡带宽评估Broker机器数
- 避免使用跨机房网路
典型线上环境
- CPU 24核
- 内存32GB
- 磁盘 1TB 7200转 SAS两块
- 宽带1Gb/s
- ulimit -n 1000000
- Socket Buffer 至少64KB - 适用于跨机房网络传输