这次我们来聊一下Kafka在实际部署时候的一些规划问题,以及部署后的一些配置项.

1.首先是操作系统的选择,虽然因为Scala也是JVM系的语言.那么理论上应该是跨平台部署的.

但是实际上比起Windows等操作系统,更加推荐Linux,部署在Linux上有两个优点,分别是IO模型和网络传输效率.

对于IO模型,主流的5种模型,阻塞IO,非阻塞IO,IO多路复用,信号驱动IO,异步IO

每一种都有典型的使用场景,Linux的epoll则是兼具第三种和第四种模型的有点

而Kakfa则是在网络库的设计上采用了Java的Selector,而在Linux上的实现机制就是epoll.

虽然,Windows提供了IOCP实现,但只有NIO2才使用了IOCP,而Kafka并没有很好的兼容.

其次是网络传输方面,Linux也更加有优势,Linux提供了sendfile系统调用,就是我们前面说的零拷贝技术.

根据上面两者的结合,更加推荐使用Linux操作系统来部署Linux系统.

2.磁盘规划

对于Kafka而言,磁盘是非常重要的一环,因为Producer将消息首先就放在了磁盘之中.而且往往只有规定数量的broker落盘成功后才会标记消息为成功.故磁盘的延迟越低,用户体验越好.

确定磁盘的时候,是选择机械硬盘还是固态磁盘,机械磁盘成本低容量大,SSD寻道时间和存取时间极低.但是就Kafka而言,其使用磁盘的方式,基本可以抵消SSD和机械硬盘的差异,因为其只是进行顺写磁盘,从而保证机械硬盘不需要频繁的移动磁头,节省了寻道的时间.

其次是kafka的集群中是使用JBOD还是RAID呢?

JBOD指的是普通磁盘,而RAID则是多个磁盘组成的磁盘阵列,组成了高可用的磁盘阵列

但是对于Kafka而言,其本身就具有冗余和高可用机制,故并不怎么需要RAID来提供高可用.

故采用JBOD性价比更高,而且可以为每个broker配置多个日志路径,每个路径都挂在不同的磁盘上,使得多个磁盘磁头可以同时执行物理IO写操作,加快Kafka消息生产的速度.

对于磁盘容量规划,Kafka需要多大的容量,这又是一个非常经典的问题,这往往需要通过多个因素来进行计算

新增消息数

消息留存时间

平均消息大小

副本数

是否启用压缩

比如每天产生一亿条消息,一条消息的大小是1KB,每天产生一亿条消息,每天产生的消息大概会占用1亿 * 2 * 1KB / 1000 /1000 = 200GB的磁盘空间,最好预留10%的空间来进行存储,这样一天大约需要210GB,整体的容量大约需要 210GB * 7,大约1.5TB.这是没有产生消息压缩的情况下.

3.内存规划

对于内存,Kafka似乎使用的不多,也不大,但是其需要进行缓存,缓存的地方就是页缓存

而对于JVM堆内存,使用的反而不多,主要使用的还是页缓存,而对于页缓存的大小,则是建议和日志文件大小有关,如果一个日志设置为1GB,那么建议设置page cache大于1GB.

4.CPU规划

CPU对于Kafka来说并不重要,但是对于CPU,Kafka还是希望核数越多越好,因为Broker有者十几个后台线程去进行处理.

5.带宽规划

对于Kafka的带宽,其实重要度也没怎么高,因为这并不是上面稀缺资源,不过越高的带宽就越有助于提高Kafka的高吞吐量.还是希望根据实际的使用搭设一个更为强大的宽带

其次是Kafka的一些参数设置

常见的参数设置有broker端参数,topic级别设置,JVM等

对于broker端的设置,都是在Kafka目录下的config/server.properties设置.对于大部分的broker参数,Kafka不支持动态修改,也就是说如果要新增,就需要重启对应的broker服务器.

常见的broker参数如下

brokerid,用于表示不同的broker的作用,参数默认是-1,不指定就是自动生成一个唯一值,实际使用中,推荐配置一个从0开始的数字序列,比如0,1,2

log.dirs,配置kafka的持久化消息目录,可以配置多个来平均磁盘的读写,从而提升吞吐量,如果不设置,默认是放在/tmp/kafka-logs作为消息保存的目录。

zookeeper.connect,配置zookeeper的地址

listeners,broker的监听器列表,用于对外暴露给clients的监听端口。

unclean.leader.election.enable,是否开启unclean leader选举,就是在leader宕机之后,ISR中无人,此时支持不在ISR中的副本当选新的leader,此选项可以提高可用性,但是谁导致消息的丢失。

delete.topic.enable,是否支持Kafka删除topic,默认情况下,是允许,实际生产情况下,也是建议设置为true。

log.retention,设置消息的留存时间。

log.retention.bytes,留存大小,为每个消息日志保存多大的数据,如果超过了,就会自动清理超过的日期段文件,默认值为-1,表示不会根据消息日志大小而删除日志。

min.insync.replicas,最小的同步成功副本数,配合ACK使用,如果需要最高等级的持久化保证,那么建议设置为-1

message.max.bytes,Broker能够收到的最大消息大小,默认是977KB,这一点需要在实际使用中根据自身情况来配置。

基本的broker端的配置说完了,接下来看看一些topic级别的参数

这些参数往往会覆盖broker级别的,从而做到不同的topic,不同的配置。

常见的包括以下几

delete.rentention.ms,每个topic拥有自己的日志留存时间

max.message.bytes,为每个topic指定不同的最大消息尺寸

retention.bytes,覆盖全局的log.rentention,bytes,为每个topic设置不同的日志留存尺寸。

对于Kafka的GC调优,由于新版本之后的kafka仅支持8以上的JDK,故使用默认的G1垃圾回收器即可。

对于JVM的配置,推荐使用最新的JDK版本,而对于堆内存的配置,不推荐使用超过6GB的堆空间。

最后是部署的系统参数,Kafka会频繁的创建并修改文件系统,故需要设置文件描述符限制,如果一个broker上有很多topic分区,那么会打开很多的文件,故需要设置进程能打开的最大文件描述符的上限,比如ulimit -n 100000

Socket的缓冲区大小,系统级别的Socket大小,如果传输的数据很大,可以考虑将Socket缓冲区增大,比如增大到128KB。

以及需要关闭SWAP这类系统默认的调优,避免降低速度

如果希望增大吞吐,那么可以通过延长磁盘flush时间来增大物理吞吐量。

总结一下,我们从部署规划和配置参数两个方面来阐述了下Kafka线上集群的搭建。

发表评论

邮箱地址不会被公开。 必填项已用*标注