kafka生产规划和运维-八零岁月
记录我所看到的
分享我所感悟的

kafka生产规划和运维

一、Kafka集群运维和规划

其实任何开源的分布式系统在开始规划时,就需要考虑到业务场景,以及生产环境的周边可观测系统,比如如下几个方面:

  • 规划和部署生产级别的集群(包含官方最佳实践以及一些针对不停场景推荐的配置项变更)
  • 执行一些部署后的操作(比如滚动重启集群,集群备份,数据迁移等等)
  • 集群的可观测性(监控重要统计数据,理解kafka内部行为的具体含义以及是否需要报警通知)

二、集群规划

本节主要介绍,kafka集群在生产环境部署前的一些规划,包含硬件配置选择,网络以及文件系统和其他考虑的选型.

1.硬件和OS

注意:通常对于分布式的开源服务来将对于硬件本身没有太高的要求,但当需要承载一定量级的业务时,我们需要考虑一些硬件是否能够支撑对应的业务场景,并且通常来讲针对不同的业务场景选择不同的硬件(如果可选择),也许会适当降低资源成本。

1.0 OS

一般来说,对于运行Linux中的kafka集群不需要过多的OS以及kernel参数调整,但如下几种情况可以根据具体情况进行参考:

  • 文件描述符(fd): broker节点上fd限制可以参考(number_of_partitions)*(partition_size/segment_size)公式
  • 套接字缓冲区(socket buffer): 该参数可以增加多数据中心之间的数据传输(一般异地集群备份建议调整以增加吞吐)
  • 最大内存映射区域数(vm.max_map_count): 当kafka broker节点拥有太多分区时应该密切关注系统级别的该参数,默认为65535。每一个日志段,分配的分区,都需要一对index/timeindex文件,而每个文件都会消耗一个内存区域(一个日志段使用2个内存映射区域),因此一个分区至少需要2个内存区域,一个broker上拥有50000分区时,将会消耗100000个内存区域,此时默认的参数就会导致broker 以OutOfMemoryError方式crash掉。

注意:每个分区的日志段的数量取决于段(segment)的大小,负载,以及保留策略

kafka使用大量的文件以及socket和客户端进行通讯,我们都知道,在Linux下,一切皆文件,因此系统需要设置更多的可用文件描述符>。

在大多数的默认系统配置中,单个进程可用使用1024个文件描述符,对于kafka来说太小了,建议调整到至少100000,但是通常和操作 系统以及发行版本有关系,需要根据具体的OS进行调整。

可用通过计算Kafka数据目录中的.index文件来计算当前的mmap编号。.index文件大多数代表了内存映射文件。

# 1.统计.index文件个数
$ find . -name ‘*index’ | wc -l
# 2.为每个session设置vm.max_map_count参数,这将计算当前内存映射文件的数量,mmap限制的最小值就是打开文件的ulimit限制 # 该值要远大于index的数量
$ sysctl -w vm.max_map_count=262144
# 3.持久化mmap参数
$ echo ‘vm.max_map_count=262144’ >> /etc/sysctl.conf $ sysctl -p

1.1 内存

Kafka严重依赖文件系统来存储和缓存消息。

所有数据都会立即写入文件系统上的持久日志中,而不必刷新到磁盘。实际上,这仅意味着将其转移到内核的页面缓存pagecache中。 当回收内存时,操作系统会将可用内存转移到磁盘缓存中,而对性能的影响很小。

同时,Kafka非常小心地使用堆空间heap space,不需要将堆大小设置为超过6 GB,这样将会在32G内存的机器上缓存28-30G的数据到文件系统。

因此,生产集群需要足够的内存来缓存活动的reader和writer。在Confluent的使用建议中,提出了对内存需求的粗略估计方式,比如需要缓冲30s,那么内存需求大概为write_throughput * 30

通常来讲64G内存配置的机器是一个不错的选择.

1.2 CPU

大多数的kafka集群对于cpu的要求不是那么高,因此对于CPU的配置没有像其他资源那么重要(但是通常同等资源都是由一定比例配比的)。

注意: 如果开启了SSL,那么可能对集群的整体性能有一定影响,且对cpu有一定要求,具体需要考虑到cpu的类型以及具体的JVM实现细节(通常来讲内部服务均不会开启SSL,因为管理成本很高,且性能上略有损失,安全上可以通过整体的IT安全进行要求和管控)

通常情况下建议使用较新的多核处理器,通用集群可以设置为24核心。

如果需要在更快的CPU或更多的内核之间进行选择,请选择更多的内核,因为多核提供的额外并发性将远远超过稍快的时钟速度。

1.3 Disk

生产集群建议使用多块磁盘来最大化整体的吞吐,不要与应用程序日志或其他OS文件系统活动共享用于Kafka数据的相同驱动器,以确保良好的延迟。

在官方的最佳实践中建议,可以将多块磁盘构建成RAID,或者直接将独立的多块磁盘作为kafka的数据存储,也就是JBOD方案(Just Bunch Of Disks)。

备注:如果软RAID的话其实会在存储方面增加一层数据均衡,增加了集群的复杂度,因此一般可用选择后者,而且RAID主要用于提供冗余,对于开源分布式服务来讲,在软件层面上基本都会保证数据的冗余。

不过在实际的场景中,具体选择使用多块盘做RAID还是直接使用多块盘挂载,以下有几种场景可以考虑:

如果配置多个数据目录,则Broker将在路径中放置一个新分区,该分区中当前存储的分区数最少。每个分区将完全位于数据目录之一中,如果分区之间的数据不平衡,就会导致磁盘之间的负载不平衡

RAID在平衡磁盘之间的负载方面做得更好,它能在较低的水平上平衡负载。RAID的主要缺点是减少了可用的磁盘空间(RAID0除外),好处是可以容忍磁盘故障(RAID1,RAID5等)。

在生产中强烈不建议使用RAID 5 or RAID 6 ,会严重影响到写吞吐的性能,并且在磁盘故障时会有重建阵列的I/O成本(RAID0下也存在重建I/O的成本)

如果额外的成本可以接受,建议使用RAID10(容量减半,多一份冗余),否则,建议Kafka服务器配置多个日志目录,每个目录都安装在单独的驱动器上。

linked使用8×7200转的sata磁盘,一般来说,磁盘吞吐量是性能瓶颈,磁盘越多越好。

kafka官方文档中其实建议使用多个驱动器以获得良好的吞吐量,因为每个路径都独立挂载在不同的磁盘上,这使得多块物理磁盘磁头同时执行物理I/O写操作,可以极大地加速Kafka消息生产的速度。

注意: 通常在使用本地盘时,容量可能会比较大,当磁盘容量超过2T时,Linux下默认的MBR分区就不能满足容量的要求了,此时需要在分区时进行GPT分区,否则等线上业务真正上线后会发现超过2T的空间就被浪费了。

另外一个问题就是,磁盘容量规划的问题,虽然kafka默认为全部的日志数据设置了7天保留时间,但是往往在海量的数据消费场景中,单天的数据量也可能达到好几个T,这就导致了需要提前对业务的场景和使用方式进行提前规划,并提前计算最少的存储量。

但一般对于磁盘空间的规划可以根据消息量大概估算,比如一天7亿条消息,单条1kb,消息副本为3(可保证2节点同时挂),那么大概的存储空间为7亿*3*1KB/1000/1000=2100G,也就是这种规模下的数据,一天产生2T的数据,实际使用数据为700G,1400G数据为冗余数据,此时我们在规划磁盘容量时就需要考虑到单天数据量的大小,以及数据的保留时间。

注意: 如果客户端开启了消息压缩,整体的数据能再相对小一些,可以根据具体情况来考虑

1.4 Network

在分布式系统中,快速可靠的网络是性能的一个重要组成部分(因此通常分布式系统中建议在同机房)。

低延迟确保节点可以轻松通信,而高带宽有助于集群节点之前的副本移动和恢复(往往在kafka集群中优先瓶颈点都是带宽)。

目前大多数的数据中心基本都是千兆(1 GbE)或万兆网络(10 GbE),对于大多数集群通常都是足够的。

应该尽量避免集群跨越多个数据中心,即使数据中心在很近的距离同地区,也要避免跨越巨大地理距离的集群。

备注:实际上在分布式系统中分区是肯定会发生的,通过避免跨机房部署能够降低分区的概率

Kafka集群假设所有节点都是相等的,较大的延迟可能会加剧分布式系统中的问题,并使调试和解决变得更加困难。

注意: 如果业务上需要异地进行数据读写,推荐的方法是在每个数据中心中部署一个本地Kafka集群,每个数据中心中的应用程序实例只与它们的本地集群交互,并在集群之间进行镜像(kafka提供了mirror-maker工具)。

1.5 Filesystem

现在操作系统中,大部分的系统应该都使用了Ext4XFS系统,官方也推荐使用这两种文件系统,但是对于具体的文件系统的选择,官方提供了如下几种场景和需要注意的点。

使用各种文件系统创建和挂载选项,在具有大量消息负载的集群上执行了比较测试,XFS带来了更好的本地时间(最好的EXT4配置是160ms vs. 250ms+),以及更低的平均等待时间。XFS性能在磁盘性能方面的可变性也较小。

不论是使用哪种文件系统,推荐修改默认的挂载参数:

  • noatime: 此选项禁止在读取文件时更新文件的atime(最后访问时间)属性,这可以消除大量的文件系统写操作,特别是在引导消费者的情况下,Kafka完全不依赖于atime属性,所以禁用它是安全的
$ cat /etc/fstab UUID=”4231b126-7e67-45c4-b8bf-554006291d35″ /export1 xfs defaults,noatime 0 2

XFS文件系统挂载参数优化:

  • largeio: 这会影响stat调用报告的首选I/O大小,尽管这可以在较大的磁盘写入上实现更高的性能,但实际上对性能的影响很小或没有影响
  • nobarrier: 于具有电池后备缓存的基础设备,此选项可以通过禁用定期写刷新来提供更高的性能。 但是,如果基础设备的行为良>好,它将向文件系统报告它不需要刷新,并且此选项将无效。

EXT文件系统挂载参数优化:

注意: 在ext4文件系统下,要获得最佳性能,则需要调整几个参数。这些选项在故障情况下通常是不安全