有的时候博客内容会有变动,首发博客是最新的,其余博客地址可能会未同步,认准https://blog.zysicyj.top

首发博客地址

文章更新打算

系列文章地址


Kafka 线上集群部署计划怎么做

操作系统

先说论断,Kafka 部署在 Linux 上要比 Windows 和 Mac 上性能高的多,次要是以下几个起因:

  1. 操作系统优化:Linux 操作系统在网络和文件系统性能方面通常比 Windows 和 Mac 更优良。Linux 内核对网络和磁盘 I/O 的解决更高效,可能更好地利用硬件资源,从而进步 Kafka 的性能。
  2. 文件系统抉择:Linux 上罕用的文件系统如 ext4、XFS 等对大规模数据处理和高并发读写有更好的反对。而 Windows 上的 NTFS 文件系统在解决大量小文件和高并发读写时性能绝对较差。
  3. 网络栈性能:Linux 的网络栈在解决高并发连贯和大规模数据传输时体现更杰出。Linux 内核对网络协议栈的优化更多,可能更好地解决网络数据包,进步 Kafka 的吞吐量和响应速度。
  4. 硬件资源管理:Linux 操作系统对硬件资源的治理更加灵便和高效。Linux 上的过程调度、内存治理等机制可能更好地利用多核处理器和大内存,进步 Kafka 的并发解决能力。
  5. 社区反对度

I/O 模型

支流的 I/O 模型通常有以下五种类型:

  1. 阻塞 I/O(Blocking I/O):在进行 I/O 操作时,应用程序会被阻塞,直到数据筹备好或者操作实现。这种模型是最简略的,然而会导致应用程序的性能降落,因为在期待 I/O 实现时,CPU 无奈解决其余工作。
  2. 非阻塞 I/O(Non-blocking I/O):在进行 I/O 操作时,应用程序能够继续执行其余工作,而不会被阻塞。然而,如果数据还没有筹备好或者操作还没有实现,应用程序须要一直地轮询来查看状态,这会导致 CPU 的资源节约。
  3. I/O 多路复用(I/O Multiplexing):通过应用 select、poll 或者 epoll 等零碎调用,应用程序能够同时监督多个文件描述符的状态,当任何一个文件描述符筹备好进行 I/O 操作时,应用程序就能够进行相应的读写操作。这种模型能够无效地解决多个连贯,进步零碎的并发性能。
  4. 信号驱动 I/O(Signal-driven I/O):应用程序通过注册信号处理函数,在数据筹备好时接管到一个信号,而后进行相应的读写操作。这种模型相比于非阻塞 I/O,缩小了轮询的开销,然而依然须要应用程序一直地检查数据是否筹备好。
  5. 异步 I/O(Asynchronous I/O):应用程序发动一个 I/O 操作后,能够继续执行其余工作,当数据筹备好或者操作实现时,操作系统会告诉应用程序进行相应的读写操作。这种模型是最高效的,因为应用程序不须要进行轮询或者阻塞期待,能够充分利用 CPU 的资源。

你不用具体理解每一种模型的实现细节,通常状况下咱们认为后一种模型会比前一种模型要高级,比方 epoll 就比 select
要好,理解到这一水平应该足以应酬咱们上面的内容了。

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

零拷贝

Kafka 在 Linux 上反对零拷贝(Zero-copy)的次要起因是 Linux 操作系统提供了一些个性和零碎调用,使得零拷贝成为可能。而 Windows 操作系统在设计上与 Linux 有所不同,因而不间接反对零拷贝。

零拷贝是一种优化技术,能够缩小数据在内核空间和用户空间之间的拷贝次数,进步数据传输的效率。在传统的拷贝形式中,数据从磁盘读取到内核缓冲区,而后再从内核缓冲区拷贝到用户空间的应用程序缓冲区,这波及到屡次数据拷贝操作,减少了 CPU 和内存的开销。

在 Linux 上,零拷贝的实现次要依赖以下几个个性和零碎调用:

  1. 文件描述符(File Descriptor):Linux 应用文件描述符来示意关上的文件,通过文件描述符能够进行文件的读写操作。
  2. 内核缓冲区(Kernel Buffer):Linux 内核提供了一块内存区域作为内核缓冲区,用于寄存从磁盘读取的数据。
  3. sendfile 零碎调用:sendfile 零碎调用能够在内核空间和用户空间之间间接传输数据,而无需通过用户空间缓冲区。

通过应用 sendfile 零碎调用,Kafka 能够间接将数据从磁盘读取到内核缓冲区,而后通过网络发送给消费者,防止了数据在内核空间和用户空间之间的屡次拷贝。

而在 Windows 上,没有相似于 Linux 的 sendfile 零碎调用,因而无奈间接实现零拷贝。在 Windows 上,数据须要通过内核空间和用户空间之间的屡次拷贝,导致性能上的损失。

一句话总结一下,在 Linux 部署 Kafka 可能享受到零拷贝技术所带来的疾速数据传输个性。

磁盘

先说论断:

  • 谋求性价比的公司能够不搭建 RAID,应用一般磁盘组成存储空间即可
  • 应用机械磁盘齐全可能胜任 Kafka 线上环境

为什么说 Kafka 能够不搭建 RAID 环境

  1. 分布式架构 :Kafka 采纳分布式架构,将音讯扩散存储在多个 Broker 节点上。每个 Broker 节点都是独立的,它们之间互相复制音讯,实现数据的冗余和高可用性。因而,即便某个节点的磁盘产生故障,其余节点依然能够提供服务,不会导致数据失落。
  2. 数据复制 :Kafka 应用正本机制来保证数据的可靠性。每个分区都能够配置多个正本,这些正本散布在不同的 Broker 节点上。当音讯写入到 Leader 正本后,Kafka 会将音讯复制到其余正本,确保数据的冗余存储。如果某个正本所在的磁盘产生故障,Kafka 会主动抉择其余正本作为 Leader,保证数据的可用性。
  3. 长久化存储 :Kafka 将音讯长久化存储在磁盘上,而不是仅保留在内存中。这样即便 Broker 节点产生故障,音讯也不会失落。Kafka 应用程序写入的形式将音讯追加到磁盘上的日志文件中,这种形式对磁盘的要求绝对较低,不须要特地高的磁盘性能。
  4. 程度扩大:Kafka 反对程度扩大,能够通过减少 Broker 节点来进步零碎的吞吐量和容量。在扩大过程中,能够抉择在新节点上增加磁盘,而不须要对现有节点进行改变。这种形式能够灵便地依据需要来调整磁盘的配置和容量。

为什么说应用机械磁盘齐全可能胜任 Kafka 线上环境

Kafka 是一个高吞吐量、低提早的分布式音讯零碎,它的性能和稳定性对于线上环境十分重要。尽管 SSD(固态硬盘)在性能方面有显著的劣势,但机械磁盘依然能够胜任 Kafka 线上环境的起因如下:

  1. 程序写入:Kafka 的特点之一是程序写入,即音讯依照程序追加到日志文件中。机械磁盘在程序写入方面的性能体现通常比拟好,因为它们具备较大的磁道和扇区,能够更好地反对间断写入操作。
  2. 容量成本低:相比于 SSD,机械磁盘的容量老本更低。对于大规模的 Kafka 集群,存储老本是一个重要的思考因素。机械磁盘能够提供更大的存储容量,使得 Kafka 可能存储更多的音讯数据。
  3. 持久性和可靠性:机械磁盘通常具备更高的持久性和可靠性。它们在写入数据时,通常会将数据缓存在磁盘的缓存区中,而后再进行长久化写入。这种写入形式能够提供更好的数据可靠性,即便在断电等异常情况下,数据也不容易失落。
  4. 成熟稳固:机械磁盘是一种成熟的存储设备,曾经在各种利用场景中失去广泛应用。相比之下,SSD 尽管在性能方面有劣势,但在稳定性和寿命方面可能存在一些问题。对于对数据可靠性要求较高的线上环境,机械磁盘可能更受信赖。

须要留神的是,只管机械磁盘能够胜任 Kafka 线上环境,但在某些特定场景下,如对提早要求十分高的利用,或者对存储容量要求十分大的利用,可能须要思考应用 SSD 等更高性能的存储设备。此外,随着技术的倒退,将来可能会有更多新型存储设备呈现,对于 Kafka 的存储需要可能会有不同的抉择。

磁盘容量

总结下磁盘容量须要思考的因素:

  • 新增音讯数
  • 音讯留存工夫
  • 均匀音讯大小
  • 备份数
  • 是否启用压缩

我举一个简略的例子来阐明该如何思考这个问题。假如你所在公司有个业务每天须要向 Kafka 集群发送 1 亿条音讯,每条音讯保留两份以避免数据失落,另外音讯默认保留两周工夫。当初假如音讯的均匀大小是 1KB,那么你能说出你的 Kafka 集群须要为这个业务预留多少磁盘空间吗?

咱们来计算一下:每天 1 亿条 1KB 大小的音讯,保留两份且留存两周的工夫,那么总的空间大小就等于 1 亿 * 1KB * 2 / 1000 / 1000 = 200GB。个别状况下 Kafka 集群除了音讯数据还有其余类型的数据,比方索引数据等,故咱们再为这些数据预留出 10% 的磁盘空间,因而总的存储容量就是 220GB。既然要保留两周,那么整体容量即为 220GB _ 14,大概 3TB 左右。Kafka 反对数据的压缩,假如压缩比是 0.75,那么最初你须要布局的存储空间就是 0.75 _ 3 = 2.25TB

带宽

举个例子,咱们应用以下假如和计算:

  1. 带宽资源:假如机房环境是千兆网络(1Gbps),即每秒解决 1Gb 的数据。
  2. 带宽利用率:假如 Kafka 服务器最多应用 70%的带宽资源,即每秒最多应用 700Mb 的带宽。
  3. 预留资源:为了防止网络丢包,咱们额定预留了 2/3 的带宽资源,即单台服务器应用带宽 240Mbps。
  4. 数据处理指标:在 1 小时内解决 1TB 的业务数据,即每秒须要解决 2336Mb 的数据。

依据以上计算,咱们得出了须要 10 台 Kafka 服务器来实现这个业务指标。这个计算还没有思考到音讯的复制,如果音讯须要额定复制两份,那么总的服务器台数还要乘以 3,即须要 30 台服务器。

在理论部署中,你能够依据本人的网络环境和业务需要进行调整和优化。

另外,如果你的环境中还波及跨机房传输,那么带宽资源的瓶颈可能会更加显著。在跨机房传输的状况下,网络提早和带宽限度都会对性能产生影响。你可能须要思考应用更高带宽的网络或者采取其余优化措施来解决这个问题。

总结起来,对于带宽资源的布局,你须要思考以下几个因素:

  1. 网络带宽:依据网络环境确定每秒解决的数据量。
  2. 带宽利用率:依据理论状况确定 Kafka 服务器应用的带宽比例。
  3. 预留资源:为了防止网络丢包,额定预留一部分带宽资源。
  4. 数据处理指标:依据业务需要确定每秒须要解决的数据量。
  5. 音讯复制:如果音讯须要复制,思考复制的数量。

依据以上因素,你能够计算出所需的 Kafka 服务器数量,并依据理论状况进行调整和优化。

小结

集群参数配置

动态参数和动静参数

动态参数是指在 Kafka 启动时配置的参数,一旦设置后,只能通过重启 Kafka 来更改。这些参数通常是对 Kafka 整体行为的全局设置,例如 Kafka 的监听端口、日志目录、正本数量等。动态参数的配置通常在 Kafka 的配置文件(如 server.properties)中进行。

动静参数是指在 Kafka 运行时能够动静批改的参数,而无需重启 Kafka。这些参数通常是对 Kafka 的某个特定组件或性能进行细粒度的调整。动静参数能够通过 Kafka 的命令行工具或 API 进行批改。

Broker

磁盘相干

在 Kafka 中,Broker 是音讯队列的外围组件,负责接管、存储和转发音讯。为了配置存储信息,咱们须要设置一些重要的参数。

  1. log.dirs:这是一个十分重要的参数,用于指定 Broker 应用的文件目录门路。这个参数没有默认值,因而必须由用户本人指定。在生产环境中,倡议为 log.dirs 配置多个门路,以进步读写性能和实现故障转移。具体格局是一个 CSV 格局,多个门路之间用逗号分隔,例如:/home/kafka1,/home/kafka2,/home/kafka3。如果有条件的话,最好将这些目录挂载到不同的物理磁盘上,以进步性能和可靠性。
  2. log.dir:这是 log.dirs 的补充参数,用于指定单个门路。在理论应用中,咱们只须要设置 log.dirs 参数即可,不须要设置 log.dir。

为什么要为 log.dirs 配置多个门路呢?这是因为多块物理磁盘同时读写数据能够进步吞吐量,同时也能实现故障转移。在 Kafka 1.1 版本之前,如果 Broker 应用的任何一块磁盘挂掉了,整个 Broker 过程都会敞开。然而从 Kafka 1.1 版本开始,引入了 Failover 性能,坏掉的磁盘上的数据会主动转移到其余失常的磁盘上,Broker 依然能够失常工作。这个改良使得咱们不再依赖 RAID 来提供数据的可靠性,而是通过多块磁盘的故障转移来实现。

须要留神的是,如果应用了多个门路,Kafka 会依据肯定的策略将音讯调配到不同的门路上,以实现负载平衡。同时,Kafka 也会主动治理磁盘空间,当某个门路的磁盘空间有余时,会主动将音讯转移到其余门路上。

总结一下,为了配置存储信息,咱们须要设置 log.dirs 参数,为其配置多个门路,最好挂载到不同的物理磁盘上。这样能够进步读写性能和实现故障转移。同时,Kafka 会主动治理磁盘空间和实现负载平衡。这些配置能够在 Kafka 的配置文件中进行设置。

Zookeeper 相干

ZooKeeper 是一个分布式协调框架,用于协调和治理 Kafka 集群的元数据信息。它负责保留 Kafka 集群的配置信息,例如 Broker 的运行状态、Topic 的创立状况、分区信息以及 Leader 正本的地位等。

在 Kafka 中,与 ZooKeeper 相干的最重要的参数是zookeeper.connect。这个参数是一个 CSV 格局的字符串,用于指定连贯到 ZooKeeper 集群的地址和端口。例如,zk1:2181,zk2:2181,zk3:2181示意连贯到三个 ZooKeeper 节点,默认端口为 2181。

如果要让多个 Kafka 集群共享同一个 ZooKeeper 集群,能够应用chroot参数来进行辨别。chroot是 ZooKeeper 的概念,相似于别名。假如有两个 Kafka 集群,别离命名为 kafka1 和 kafka2,那么能够将zookeeper.connect参数设置为zk1:2181,zk2:2181,zk3:2181/kafka1zk1:2181,zk2:2181,zk3:2181/kafka2。这样就能够通过chroot来辨别不同的 Kafka 集群。

须要留神的是,chroot只须要在参数中指定一次,并且应该增加到最初。有时候会遇到这样的谬误格局:zk1:2181/kafka1,zk2:2181/kafka2,zk3:2181/kafka3,这是不正确的。

总结一下,设置与 ZooKeeper 相干的参数时,须要留神以下几点:

  1. zookeeper.connect参数是一个 CSV 格局的字符串,用于指定连贯到 ZooKeeper 集群的地址和端口。
  2. 如果多个 Kafka 集群共享同一个 ZooKeeper 集群,能够应用chroot参数来进行辨别。
  3. chroot参数只须要在参数中指定一次,并且应该增加到最初。

上面是一个示例配置:

zookeeper.connect=zk1:2181,zk2:2181,zk3:2181/kafka1

这个配置示意连贯到三个 ZooKeeper 节点,并应用kafka1作为chroot

Broker 相干

在 Kafka 中,listeners 参数用于指定内部连贯者通过什么协定拜访 Kafka 服务。它是一个逗号分隔的三元组列表,每个三元组由协定名称、主机名和端口号组成。协定名称能够是规范的协定,如 PLAINTEXT 示意明文传输,SSL 示意应用 SSL 或 TLS 加密传输等,也能够是自定义的协定名称。

举个例子,如果你定义了一个名为 CONTROLLER 的自定义协定,你能够在 listeners 参数中增加 CONTROLLER://localhost:9092,示意该协定通过 localhost 的 9092 端口进行通信。

须要留神的是,如果你自定义了协定名称,你还须要通过 listener.security.protocol.map 参数通知 Kafka 应用哪种平安协定。比方,如果你定义了 CONTROLLER 协定,并且该协定应用明文传输数据,你须要设置 listener.security.protocol.map=CONTROLLER:PLAINTEXT

另外,主机名和端口号比拟直观,不须要过多解释。然而须要留神的是,倡议在 Broker 端和客户端利用的配置中都应用主机名而不是 IP 地址。因为在 Kafka 的源代码中,也是应用主机名进行连贯的。如果你在某些中央应用了 IP 地址进行连贯,可能会导致连贯失败的问题。

总结一下,listeners 参数用于指定 Kafka 服务的监听器,通知内部连贯者通过什么协定拜访 Kafka。它是一个三元组列表,每个三元组由协定名称、主机名和端口号组成。倡议应用主机名而不是 IP 地址进行配置。如果应用自定义协定,还须要通过 listener.security.protocol.map参数指定平安协定。

Topic 相干

auto.create.topics.enable

该参数用于管制是否容许主动创立 Topic。倡议将该参数设置为 false,即不容许主动创立 Topic。

在线上环境中,如果该参数被设置为 true,可能会导致呈现很多名字稀奇古怪的 Topic。例如,当咱们想要为名为 test 的 Topic 发送事件时,因为拼写错误将 test 写成了 tst,启动生产者程序后,一个名为 tst 的 Topic 就会被主动创立。这种状况下,好的运维应该避免这种状况的产生,特地是对于大公司而言,每个部门被调配的 Topic 应该由运维严格把控,不容许自行创立任何 Topic。

unclean.leader.election.enable

该参数用于管制是否容许 Unclean Leader 选举。Unclean Leader 选举是指在 Kafka 中,当保留数据较多的正本都挂掉时,是否容许从保留数据较少的正本中选举出新的 Leader。

在 Kafka 中,每个分区都有多个副原本提供高可用性,其中只有一个正本对外提供服务,即 Leader 正本。只有保留数据较多的正本才有资格竞选 Leader,而那些落后进度太多的正本没有资格竞选。

如果设置unclean.leader.election.enable为 false,那么 Kafka 将保持之前的准则,坚定不容许那些落后太多的正本竞选 Leader。这样做的结果是该分区将不可用,因为没有 Leader。

如果设置unclean.leader.election.enable为 true,那么 Kafka 容许从那些保留数据较少的正本中选举出新的 Leader。这样做的结果是数据有可能失落,因为这些正本保留的数据原本就不全,当成为 Leader 后,它自身就变得收缩了,认为本人的数据才是权威的。

须要留神的是,该参数在最新版的 Kafka 中默认为 false。然而因为社区对该参数的默认值进行了屡次更改,所以倡议在应用时显式地将其设置为 false。

auto.leader.rebalance.enable

该参数用于管制是否容许 Kafka 定期进行 Leader 选举。倡议将该参数设置为 false。

设置auto.leader.rebalance.enable为 true 示意容许 Kafka 定期对一些 Topic 分区进行 Leader 重选举。须要满足肯定的条件才会触发 Leader 重选举。

unclean.leader.election.enable参数不同的是,auto.leader.rebalance.enable并不是选举新的 Leader,而是更换现有的 Leader。例如,如果 Leader A 始终体现良好,然而当auto.leader.rebalance.enable为 true 时,通过一段时间后,Leader A 可能会被强制卸任,换成 Leader B。

须要留神的是,Leader 的更换代价很高。本来向 Leader A 发送申请的所有客户端都须要切换成向 Leader B 发送申请。而且这种 Leader 的更换实质上没有任何性能收益。

因而,在生产环境中,倡议将auto.leader.rebalance.enable设置为 false,防止不必要的 Leader 更换。

数据留存方面

在 Kafka 中,有一组参数用于控制数据的留存。上面我将一一介绍这些参数。

  1. log.retention.{hours|minutes|ms}:这是一组参数,用于管制音讯数据在 Kafka 中保留的工夫。这三个参数别离是以小时(hours)、分钟(minutes)和毫秒(ms)为单位的工夫距离。优先级上,ms 设置最高,minutes 次之,hours 最低。通常状况下,咱们会设置较长的工夫距离,比方 log.retention.hours=168 示意默认保留 7 天的数据,主动删除 7 天前的数据。如果将 Kafka 用作存储系统,那么这个值可能须要相应调大。
  2. log.retention.bytes:这个参数用于指定 Broker 在磁盘上保留的音讯数据的总容量大小。默认值为-1,示意没有容量限度,即能够保留任意大小的数据。这个参数在构建云上的多租户 Kafka 集群时发挥作用。假如你要提供一个云上的 Kafka 服务,每个租户只能应用 100GB 的磁盘空间,为了防止某个租户占用过多的磁盘空间,设置这个参数就十分重要了。
  3. message.max.bytes:这个参数用于管制 Broker 可能接管的最大音讯大小。默认值为 1000012,即不到 1MB。然而,在理论场景中,超过 1MB 的音讯是很常见的。因而,在生产环境中,将这个值设置得比拟大是比拟保险的做法。这个参数只是一个标尺,仅仅掂量 Broker 可能解决的最大音讯大小,即便设置得大一点也不会占用太多磁盘空间。

须要留神的是,这些参数都是可配置的,能够依据理论需要进行调整。在配置文件中,能够通过设置对应的属性来批改这些参数的值。例如,能够在server.properties文件中增加以下配置来批改log.retention.hours参数的值:

log.retention.hours=168

这样就将音讯数据的保留工夫设置为 7 天。

总结一下,这些参数在 Kafka 中起到了重要的作用,能够依据理论需要来调整,以满足不同的业务场景。

Topic 级别参数

Topic 级别的参数在 Kafka 中十分重要,它容许咱们为每个 Topic 设置特定的参数值,这些参数会笼罩全局 Broker 参数的值。这样做的益处是能够依据不同的业务需要,为不同的 Topic 设置不同的参数,进步零碎的灵活性和效率。

上面我将具体介绍几个重要的 Topic 级别参数,依照用处分组。

  1. 保留音讯方面的参数:

    • retention.ms:规定了该 Topic 音讯被保留的时长。默认值是 7 天,即该 Topic 只保留最近 7 天的音讯。如果设置了这个值,它会笼罩 Broker 端的全局参数值。通过设置不同的 retention.ms 值,咱们能够依据业务需要来管制音讯的保留时长,防止有效的数据占用过多的存储空间。
    • retention.bytes:规定了为该 Topic 预留的磁盘空间大小。和全局参数的作用相似,这个值在多租户的 Kafka 集群中十分有用。默认值是-1,示意能够有限应用磁盘空间。通过设置不同的 retention.bytes 值,咱们能够依据不同的 Topic 的数据量来正当调配磁盘空间,防止存储空间有余的问题。
  2. 解决音讯大小方面的参数:

    • max.message.bytes:决定了 Kafka Broker 可能失常接管该 Topic 的最大音讯大小。在很多公司中,Kafka 作为基础架构组件运行,承载了大量的业务数据。如果在全局层面上无奈给出一个适合的最大音讯值,那么容许不同的业务部门自行设定 Topic 级别的max.message.bytes参数就显得十分必要了。通过设置不同的max.message.bytes值,咱们能够依据不同的业务需要来管制音讯的大小,确保零碎可能失常解决各种大小的音讯。

通过设置 Topic 级别的参数,咱们能够依据不同的业务需要来灵便地调整 Kafka 的配置,进步零碎的性能和可用性。同时,这也是 Kafka 作为一个高性能分布式音讯零碎的重要个性之一。

须要留神的是,Topic 级别的参数只对该 Topic 中的音讯失效,不会影响其余 Topic。如果没有为某个 Topic 设置特定的参数值,那么将会应用全局 Broker 参数的默认值。

除了上述介绍的参数,Kafka 还有其余一些 Topic 级别的参数,如cleanup.policycompression.type等,它们都能够依据具体的业务需要进行设置。在理论利用中,咱们能够依据不同的场景和需要,灵便地应用这些参数来优化 Kafka 集群的性能和可靠性。

总结一下,Topic 级别的参数容许咱们为每个 Topic 设置特定的参数值,笼罩全局 Broker 参数的值。通过设置不同的参数值,咱们能够依据业务需要来管制音讯的保留时长、磁盘空间应用和音讯大小等,进步零碎的灵活性和效率。这是 Kafka 作为一个高性能分布式音讯零碎的重要个性之一。

在 Kafka 中,能够通过两种形式来设置 Topic 级别的参数:在创立 Topic 时设置和批改已存在的 Topic 时设置。

1. 创立 Topic 时设置参数

在创立 Topic 时,能够通过--config参数来设置 Topic 级别的参数。例如,咱们要创立一个名为transaction的 Topic,并设置retention.ms为 15552000000,max.message.bytes为 5242880,能够应用以下命令:

bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic transaction --partitions 1 --replication-factor 1 --config retention.ms=15552000000 --config max.message.bytes=5242880

在上述命令中,--config前面的参数用于指定要设置的 Topic 级别参数。

2. 批改已存在的 Topic 时设置参数

能够应用kafka-configs命令来批改已存在的 Topic 的参数。假如咱们要将transaction Topic 的max.message.bytes批改为 10485760,能够应用以下命令:

bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name transaction --alter --add-config max.message.bytes=10485760

在上述命令中,--entity-type topics示意要批改的实体类型为 Topic,--entity-name transaction示意要批改的 Topic 名称,--alter示意要进行批改操作,--add-config前面的参数用于指定要批改的 Topic 级别参数及其新值。

集体倡议

集体倡议始终保持应用第二种形式来设置 Topic 级别参数,并且在将来,Kafka 社区很有可能对立应用kafka-configs脚本来调整 Topic 级别参数。这样做的益处是对立了设置参数的形式,缩小了学习老本和混同,同时也更加方便管理和保护。

JVM 参数

JVM 参数对于 Kafka 集群的性能和稳定性十分重要。在设置 JVM 参数之前,首先须要确定 Java 版本。对于 Kafka 来说,不举荐在 Java 6 或 7 的环境上运行,倡议至多应用 Java 8。

在 JVM 参数设置中,堆大小是一个要害参数。只管前面咱们还会探讨如何调优 Kafka 性能的问题,然而当初我想给出一个通用的倡议:将 JVM 堆大小设置为 6GB,这是目前业界广泛认可的一个正当值。很多人应用默认的堆大小来运行 Kafka,然而默认的 1GB 有点小,因为 Kafka Broker 在与客户端进行交互时会在 JVM 堆上创立大量的 ByteBuffer 实例,堆大小不能太小。

另一个重要的 JVM 参数是垃圾回收器(GC)的设置。如果你仍在应用 Java 7,能够依据以下规定抉择适合的垃圾回收器:如果 Broker 所在机器的 CPU 资源十分富余,倡议应用 CMS(Concurrent Mark Sweep)收集器,启用办法是指定-XX:+UseConcMarkSweepGC。否则,应用吞吐量收集器,启用办法是指定-XX:+UseParallelGC。如果你应用 Java 8,能够手动设置应用 G1(Garbage First)收集器。在没有任何调优的状况下,G1 体现要比 CMS 更杰出,次要体现在更少的 Full GC 和须要调整的参数更少等方面,所以应用 G1 就能够了。

当初咱们确定了要设置的 JVM 参数,接下来咱们来为 Kafka 进行设置。奇怪的是,这个问题在 Kafka 官网上竟然没有被提及。实际上,设置的办法非常简单,你只须要设置上面这两个环境变量即可:

  • KAFKA_HEAP_OPTS:指定堆大小。例如,你能够这样设置:export KAFKA_HEAP_OPTS="-Xms6g -Xmx6g"
  • KAFKA_JVM_PERFORMANCE_OPTS:指定 GC 参数。例如,你能够这样设置:export KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true"

在启动 Kafka Broker 之前,先设置好这两个环境变量,而后执行启动命令,例如:

$ export KAFKA_HEAP_OPTS="-Xms6g -Xmx6g"$ export KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true"$ bin/kafka-server-start.sh config/server.properties

这样就实现了 JVM 参数的设置。通过正当的设置,能够进步 Kafka 集群的性能和稳定性。须要留神的是,具体的参数设置可能因环境和需要而有所不同,能够依据理论状况进行调整。

操作系统参数

Kafka 集群通常须要设置一些操作系统参数来优化性能和稳定性。上面是一些常见的操作系统参数设置:

  1. 文件描述符限度(ulimit -n):文件描述符是操作系统用于跟踪关上文件的标识符。Kafka 集群须要同时关上大量的文件描述符,因而须要减少文件描述符限度。默认状况下,操作系统的文件描述符限度较低,可能会导致 Kafka 过程无奈关上足够的文件描述符,从而影响性能。倡议将文件描述符限度设置为一个较大的值,例如 ulimit -n 1000000。
  2. 文件系统类型的抉择:Kafka 集群的性能和稳定性受到文件系统的影响。依据官网测试报告,XFS 文件系统的性能要优于 ext4 文件系统。因而,在生产环境中最好抉择 XFS 文件系统。最近也有一些对于 Kafka 应用 ZFS 文件系统的报告,显示其性能更强劲,如果条件容许,能够尝试应用 ZFS 文件系统。
  3. Swap 的调优:Swap 是操作系统用于将内存中不罕用的数据临时存储在磁盘上的机制。一些文章倡议将 Swap 设置为 0,齐全禁用 Swap,以避免 Kafka 过程应用 Swap 空间。然而,集体认为最好不要将 Swap 设置为 0,而是设置为一个较小的值。这是因为当物理内存耗尽时,操作系统会触发 OOM killer 组件,随机抉择一个过程并杀死它,而不给用户任何预警。如果将 Swap 设置为一个较小的值,当开始应用 Swap 空间时,你至多能察看到 Broker 性能的急剧下降,从而有工夫进行进一步的调优和问题诊断。倡议将 swappiness 设置为靠近 0 但不为 0 的值,例如 1。
  4. 提交工夫(Flush 落盘工夫):Kafka 发送数据时,并不需要期待数据被写入磁盘才认为胜利,只有数据被写入操作系统的页缓存(Page Cache)即可。操作系统会依据 LRU 算法定期将页缓存上的“脏”数据写入物理磁盘。提交工夫决定了这个定期的距离,默认为 5 秒。通常状况下,这个工夫距离可能太频繁,能够适当减少提交工夫距离来升高物理磁盘的写操作。须要留神的是,如果数据在写入磁盘之前产生机器宕机,数据将会失落。但因为 Kafka 在软件层面提供了多正本的冗余机制,因而能够适当减少提交工夫距离以换取性能。

须要留神的是,以上参数设置是个别状况下的倡议,具体的设置还须要依据理论状况和硬件配置进行调整。另外,不同的操作系统和版本可能会有不同的参数设置形式,请参考相应的操作系统文档或官网倡议进行设置。

上面是一个示例,展现如何在 Linux 零碎上设置 ulimit -n 参数:

# 查看以后文件描述符限度ulimit -n# 批改文件描述符限度为 1000000ulimit -n 1000000# 验证批改是否失效ulimit -n

请留神,以上示例仅实用于 Linux 零碎,其余操作系统可能有不同的设置形式。

<!-- md plan/kafka.md -->
<!-- md tj.md -->

本文由mdnice多平台公布