Kafka产线集群部署

单机构成的Kafka伪集群只能用于日常测试用,根本无法满足实际的线上生产需要,而真正的线上环境需要仔细地考量各种因素,结合自身的业务需求而制定,本文分别从操作系统、磁盘、磁盘容量和带宽等方面来讨论。

操作系统

首先我们先看看要把Kafka安装到什么操作系统上。说起操作系统,你可能会问Kafka不是JVM系的大数据框架吗?Java又是跨平台的语言,把Kafka安装到不同的操作系统上会有什么区别吗?其实区别相当大!

的确,如你所知,Kafka由Scala语言和Java语言编写而成,编译周的源代码就是普通的.class文件。本来部署到哪个操作系统应该都是一样的,但是不同操作系统的差异还是给Kafka集群带来了相当大的影响。目前常见的操作系统有3种:LInux、Windows和macOS。应该说部署在Linux上的生产环境是最多的,也是一些Kafka集群部署在Windows服务器上。Mac虽然也有macOS Server,但是我怀疑是否有人真的把生产环境部署在mac服务器上。

如果考虑操作系统和Kafka的适配性,Linux系统显然要比其他两个特别是Windows系统更加适合部署Kafka,这个结论可能很多人都知道,但是其中具体的原因也一定要了解:

  • I/O模型的使用
  • 数据网络传输效率
  • 社区支持度

分别解释一些,首先来看I/O模型。什么是I/O模型呢?你可以近似地认为I/O模型就是操作系统执行I/O指令的方法。

主流的I/O模型通常有5种类型:阻塞式I/O、非阻塞式I/O、I/O多路复用、信号驱动I/O和异步I/O。每种I/O模型都有各自典型的使用场景,比如Java中的Socket对象的阻塞模式和非阻塞模式就对应于前两种模型;而Linux中的系统调用select函数就属于I/O多路复用模型;大名鼎鼎的epoll系统调用则介于第三种和第四种函数之间;至于第五种模型,其实很少有Linux系统支持,反而是Windows系统提供了一个叫IOCP线程模型属于这一种。

你不比详细了解每一种模型的实现细节,通常情况下我们认为后一种模型会比前一种模型要高级,比如epoll就比select要好,了解到这一程度就足以。

说了这么多,I/O模型与Kafka的关系又是什么呢?实际上Kafka客户端底层使用了Java的selector,selector在Linux上实现机制是二poll,而在Windows平台上的实现机制是select。因此在这一点上将Kafka部署在Linux上是有优势的,因为能够获得更高效的I/O性能。

其次是网络传输效率的差别。你知道的,Kafka生产和消费的消息都是通过网络传输的,而消息保存在哪里呢?肯定是磁盘,故Kafka需要在磁盘和网络间进行大量数据传输。如果你熟悉Linx,你肯定听过零拷贝(Zero Copy)技术,就是当数据在磁盘和网络进行传输时避免昂贵的内核态数据拷贝从而实现快速的数据传输。Linux平台实现了这样的零拷贝机制,但令人遗憾的是Windows平台上必须要等到Java 8的60更新版本才能“享受”到这个福利。一句话总结,在Linx部署Kafka能够享受到零拷贝技术所带来的快速数据传输特性

最后是社区的支持度。这一点虽然不是什么明显的差别,但如果不了解的话可能比前两个因素对你的影响更大。简单来说就是,社区目前对Windows平台发现的Kafka Bug不做任何承诺。虽然口头上依然保证尽力去解决,但是根据经验看,Windows上的bug一般不会修复的。因此,Windows平台上部署Kafka只适合于个人测试或用于功能验证,千万不要应用于生产环境

磁盘

如果问哪种资源对Kafka性能最重要,磁盘无疑是靠前的位置,在对Kafka集群进行磁盘规划时经常面对的问题是,我们应该选择普通的机械硬盘还是固态硬盘?前者成本低且容量大,但易损坏;后者性能优势大,不过单价高,建议使用普通的机械硬盘即可。

Kafka大量使用磁盘不假,可它使用的方式多是顺序读写操作,一定程度上规避了机械磁盘最大的劣势,即随机读写操作慢。从这一点上看,使用SSD似乎并没有太大的性能优势,毕竟从性价比上来说,机械磁盘物美价廉,而它因易损坏而造成的可靠性差等缺陷,又由Kafka在软件层面提供机制来保护,故使用普通机械磁盘是很划算的。

关于磁盘选择另一个经常讨论的话题就是到底是否应该使用磁盘阵列(RAID)。使用RAID的两个主要优势在于:

  • 提供冗余的磁盘存储空间
  • 提供负载均衡

以上两个优势对于任何一个分布式系统都很有吸引力,不过就Kafka而言,一方面Kafka自己实现了冗余机制来提供高可用性;另一方面通过分区的概念,Kafka也能在软件层自己实现负载均衡。如果说来RAID的优势就没有那么明显了。当然这并不是说RAID不好,实际上依然很多大厂确实是把Kafka底层的存储交给RAID的,只是目前Kafka在存储这方面提供了越来越便捷的高可靠性方案,因此在线上环境使用RAID似乎变得不是那么重要了。综合以上的考量,给出的建议:

  • 追求性价比的公司可以不搭建RAID,使用普通磁盘组成存储空间即可。
  • 使用机械磁盘完全能够胜任Kafka线上环境。

磁盘容量

Kafka集群到底需要多大的存储空间?这是一个非常经典的规划问。Kafka需要将消息保证在底层的磁盘上,这些消息会被保存一段时间然后自动被删除,虽然这段时间是可以配置的,但你应该如何结合自身业务场景和存储需求来规划Kafka集群的存储容量呢?

我举一个简单例子来说明该如何思考这个问题。假设你所在公司有个业务每天需要向Kafka集群发送1亿条消息,每条消息保存两份以防止数据丢失,另外消息默认保存两周时间。假设消息的平均大小是1KB,那么你能说出你的Kafka集群需要为这个业务预留多少磁盘空间吗?

我们来计算一下:每天1亿条1KB大小的消息,保存两份且留存两周的时间,那么总空间大小就等于1亿1KB2/1000/1000 = 200GB。一般情况下,Kafka集群除了消息数据还有其他类型的数据,比如索引数据等,故我们再为这些数据预留出10%的磁盘空间,因此总的存储容量就是220GB。既然要保存两周,那么整体容量即为220GB * 14,大约3TB左右,Kafka支持数据的压缩,假设压缩比是0.75,那么最后你需要规划的存储空间就是0.75 *3 = 2.25TB。

总之在规划磁盘容量时你需要考虑下面这几个元素:

  • 新增消息数
  • 消息留存时间
  • 平均消息大小
  • 备份数
  • 是否启用压缩

带宽

对于Kafka这种通过网络大量进行数据传输的框架而言,带宽特别容易成为瓶颈。事实上,在我接触的真实案例中,带宽资源不足导致Kafka出现性能问题的比例至少占6成以上。如果你的环境中还涉及跨机房传输,那么情况可能就更糟了。

与其说是带宽资源的规划,其实真正规划的是所需的Kafka服务器的数量,假设你公司的机房环境是千兆网络,即1Gbps,现在你有个业务,其业务目标或SLA是在1个小时内处理1TB的业务数据。那么问题来了,你到底需要多少台Kafka服务器来完成这个业务呢?

让我们来计算一下,由于带宽是1Gbps,即每秒处理1GB的数据,假设每台Kafka服务器都安装在专属的机器上,也就是每台Kafka集群上没有混布其他服务,毕竟真实环境不建议这么做。通常情况下你只能假设Kafka会用到70%的带宽资源,因为总要为其他应用或进程留一些资源。

根据实际使用经验,超过70%的阈值就有网络丢包的可能性了,故70%的设定是一个比较合理的值,也就是单台Kafka服务器最多也就只能使用大约700MB的带宽资源。

稍等,这只是它能使用的最大带宽资源,你不能让Kafka服务器常规性使用这么多资源,故通常情况下要再额外预留出2/3的资源,即单台服务器使用带宽约等于240Mbps。需要提示的是,这里的2/3其实是相当保守的,你可以结合你自己的机器的使用情况酌情减少此值。

好了,有了240Mbps,我们就可以计算1小时内处理1TB数据所需要的服务器数量了,。根据这个目标,我们每秒需要处理2336MB的数据,除以240,约等于10台服务器,如果还需要额外复制两份,那么总的服务器台数还要乘以3,即30台。

学习来源: 极客时间 《Kafka核心技术与实战》学习笔记 Day06

你可能感兴趣的:(学习笔记,java,kafka,开发语言)