内存估算
您需要足够的内存来缓冲活动的读取器和写入器。 您可以通过假设您希望能够缓冲 30 秒并将您的内存需求计算为 write_throughput*30 来对内存需求进行粗略估计。
操作系统
Kafka 可以在任何 unix 系统上运行良好,并且已经在 Linux 和 Solaris 上进行了测试。
我们已经看到在 Windows 上运行的一些问题,Windows 目前不是一个受支持的平台,尽管我们很乐意改变它。
不太可能需要大量的操作系统级调整,但有三个潜在的重要操作系统级配置:
文件描述符限制:Kafka 将文件描述符用于日志段和打开的连接。 如果broker托管许多分区,请考虑broker至少需要 (number_of_partitions)*(partition_size/segment_size) 来跟踪除broker建立的连接数之外的所有日志段。 我们建议至少 100000 个允许的broker进程文件描述符作为起点。 注意: mmap() 函数添加了对与文件描述符 fildes 关联的文件的额外引用,该文件描述符上的后续 close() 不会删除该文件。 当没有更多映射到文件时,将删除此引用。
进程可能拥有的最大内存映射区域数(又名 vm.max_map_count)。 请参阅 Linux 内核文档。 在考虑broker可能拥有的最大分区数时,您应该密切关注这个操作系统级别的属性。 默认情况下,在许多 Linux 系统上,vm.max_map_count 的值大约为 65535。每个分区分配的每个日志段需要一对 index/timeindex 文件,每个文件占用 1 个映射区域。 换句话说,每个日志段使用 2 个 区域。 因此,每个分区至少需要 2 个映射区域,只要它承载单个日志段。 也就是说,在broker上创建 50000 个分区将导致分配 100000 个映射区域,并可能导致broker在具有默认 vm.max_map_count 的系统上崩溃并出现 OutOfMemoryError(映射失败)。 请记住,每个分区的日志段数取决于段大小、负载强度、保留策略,并且通常往往不止一个。
最大套接字缓冲区大小:可以增加以实现数据中心之间的高性能数据传输,如此处所述。
磁盘与文件系统
我们建议使用多个驱动器来获得良好的吞吐量,并且不要与应用程序日志或其他操作系统文件系统活动共享用于 Kafka 数据的相同驱动器以确保良好的延迟。 您可以将这些驱动器 RAID 组合到一个卷中,也可以格式化并将每个驱动器安装为自己的目录。 由于 Kafka 具有复制功能,因此也可以在应用程序级别提供 RAID 提供的冗余。 这种选择有几个权衡。
如果您配置多个数据目录,多个分区将被分配到多个数据目录。 并且每个分区将完全位于其中一个数据目录中。 如果数据在分区之间没有很好地平衡,这可能会导致磁盘之间的负载不平衡。
RAID 可能在平衡磁盘之间的负载方面做得更好(尽管它似乎并不总是如此),因为它在较低级别平衡负载。 RAID 的主要缺点是它通常会严重影响写入吞吐量的性能并减少可用磁盘空间。
RAID 的另一个潜在好处是能够容忍磁盘故障。 然而,我们的经验是,重建 RAID 阵列是 I/O 密集型的,它有效地禁用了服务器,因此这并没有提供多少真正的可用性改进。
应用与缓存刷新管理
Kafka 总是立即将所有数据写入文件系统,并支持配置刷新策略的能力,该策略控制何时使用刷新将数据强制从操作系统缓存中移出到磁盘上。 可以控制此刷新策略以在一段时间后或在写入一定数量的消息后强制将数据写入磁盘。 此配置中有多种选择。
Kafka 最终必须调用 fsync 才能知道数据已被刷新。 当从任何未知的 fsync’d 日志段的崩溃中恢复时,Kafka 将通过检查其 CRC 来检查每条消息的完整性,并重建随附的偏移索引文件作为启动时执行的恢复过程的一部分。
请注意,Kafka 中的持久性不需要将数据同步到磁盘,因为故障节点将始终从其副本中恢复。
我们建议使用完全禁用应用程序 fsync 的默认刷新设置。 这意味着依赖操作系统完成的后台刷新和 Kafka 自己的后台刷新。 这为大多数用途提供了所有领域中最好的:无需调整配置、出色的吞吐量和延迟,以及完全恢复保证。 我们通常认为复制提供的保证比同步到本地磁盘更强,但是偏执狂仍然可能更喜欢同时支持应用程序级 fsync 策略。
使用应用程序级刷新设置的缺点是它的磁盘使用模式效率较低(它使操作系统重新排序写入的余地较小)。并且它会引入延迟,因为大多数 Linux 文件系统中的 fsync 会阻止写入文件,而后台刷新会执行更细粒度的页面级锁定。
一般来说,您不需要对文件系统进行任何底层调整,但在接下来的几节中,我们将讨论其中的一些内容,以防万一。
理解Linux操作系统的缓存刷新行为
在 Linux 中,写入文件系统的数据保存在页面缓存中,直到必须将其写出到磁盘(由于应用程序级 fsync 或操作系统自己的刷新策略)。 数据的刷新由一组称为 pdflush 的后台线程完成(或在 2.6.32 后的内核中“刷新线程”)。
Pdflush 有一个可配置的策略,用于控制可以在缓存中维护多少脏数据以及必须将其写回磁盘前多长时间。此处描述了此策略。当 Pdflush 跟不上写入数据的速度时,它最终会导致写入过程阻塞写入中产生的延迟,从而减慢数据的积累速度。
您可以通过执行查看操作系统内存使用的当前状态
> cat /proc/meminfo
这些值的含义在上面的链接中有描述。
与进程内缓存相比,使用 pagecache 有几个优点,用于存储将被写出到磁盘的数据:
-
I/O 调度程序会将连续的小写操作批处理为更大的物理写操作,从而提高吞吐量。
-
I/O 调度程序将尝试重新排序写入以最小化磁盘磁头的移动,从而提高吞吐量。
-
它会自动使用机器上的所有空闲内存
文件系统选择
Kafka 使用磁盘上的常规文件,因此它对特定文件系统没有硬性依赖。 然而,使用最多的两个文件系统是 EXT4 和 XFS。 从历史上看,EXT4 有更多的使用,但最近对 XFS 文件系统的改进表明,它具有更好的 Kafka 工作负载性能特征,而不会影响稳定性。
比较测试是在具有大量消息负载的集群上执行的,使用各种文件系统创建和挂载选项。 Kafka 中受监控的主要指标是“请求本地时间”,表示追加操作所花费的时间。 XFS 带来了更好的本地时间(160 毫秒对 250 毫秒 + 最佳 EXT4 配置),以及更低的平均等待时间。 XFS 性能在磁盘性能方面的变化也较小。
一般文件系统建议
对于任何用于数据目录的文件系统,在 Linux 系统上,建议在挂载时使用以下选项:
- noatime:该选项禁止在读取文件时更新文件的 atime(上次访问时间)属性。 这可以消除大量的文件系统写入,尤其是在引导消费者的情况下。 Kafka 根本不依赖 atime 属性,因此禁用它是安全的。
XFS文件系统建议
XFS 文件系统具有大量的自动调整功能,因此它不需要在默认设置中进行任何更改,无论是在文件系统创建时还是在安装时。 唯一值得考虑的调整参数是:
-
largeio:这会影响 stat 调用报告的首选 I/O 大小。 虽然这可以在更大的磁盘写入上实现更高的性能,但实际上它对性能的影响很小或没有影响。
-
nobarrier:对于具有battery-backed缓存的底层设备,此选项可以通过禁用定期写入刷新来提供更高的性能。 但是,如果底层设备表现良好,它将向文件系统报告它不需要刷新,并且此选项将不起作用。
EXT4文件系统建议
EXT4 是适用于 Kafka 数据目录的文件系统选择,但是要从中获得最大性能需要调整几个挂载选项。 此外,这些选项在故障情况下通常是不安全的,并且会导致更多的数据丢失和损坏。 对于单个 Broker 故障,这不是什么大问题,因为可以擦除磁盘并从集群重建副本。 在多次故障的情况下,例如断电,这可能意味着底层文件系统(以及数据)损坏且不易恢复。 可以调整以下选项:
-
data=writeback:Ext4 默认为 data=ordered,这对某些写入设置了强顺序。 Kafka 不需要这种排序,因为它对所有未刷新的日志进行非常偏执的数据恢复。 此设置消除了排序约束,似乎显着减少了延迟。
-
禁用日志:日志是一种权衡:它使服务器崩溃后重新启动更快,但它引入了大量额外的锁定,从而增加了写入性能的差异。 那些不关心重启时间并希望减少写入延迟峰值的主要来源的人可以完全关闭日志。
-
commit=num_secs:这会调整 ext4 提交到其元数据日志的频率。 将此设置为较低的值可减少崩溃期间未刷新数据的丢失。 将此设置为更高的值将提高吞吐量。
-
nobh:当使用 data=writeback 模式时,此设置控制额外的排序保证。 这对于 Kafka 应该是安全的,因为我们不依赖于写入顺序并提高了吞吐量和延迟。
-
delalloc:延迟分配意味着文件系统在物理写入发生之前避免分配任何块。 这允许 ext4 分配较大的范围而不是较小的页面,并有助于确保数据按顺序写入。 此功能非常适合吞吐量。 它似乎确实涉及文件系统中的一些锁定,这增加了一些延迟差异。
本文为从大数据到人工智能博主「xiaozhch5」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://lrting.top/backend/2421/