6.5 硬件和操作系统
您需要足够的内存来缓存活动的readers和writers。您可以通过假设您希望缓存30秒,将您的内存需求计算为write_throughput * 30来进行内存需求的后期估计。
磁盘的吞吐量很重要。我们有8x7200转的SATA硬盘。通常磁盘的吞吐量是瓶颈,磁盘是越多越好。您能不能从更昂贵的磁盘中受益取决于你的刷新配置(如果您经常强制刷新,那么更高转速的SAS硬盘可能更好)。
OS
Kafka应该在任何Unix系统运行良好,并且已经在Linux和Solaris上进行了测试。我们已经发现了在windows运行的一些问题,目前windows还不是一个理想的支持平台,虽然我们很乐意改变这个问题。
Kafka不需要太多的操作系统层面的调优,但是有两个潜在重要的操作系统级别的配置:
- 文件描述符限制: Kafka把文件描述符用于日志段和打开连接。如果一个broker上有许多分区,则考虑broker至少(number_of_partitions)*(partition_size/segment_size) 个文件描述符来跟踪所有的日志段和broker所创建的连接。我们推荐每一个broker一开始至少配置100000个文件描述符。
- 最大套接字缓冲区大小:可以增加以实现数据中心之间的高性能数据传输,如此处所述。
磁盘和文件系统
我们建议使用多个驱动器以获得良好的吞吐量,并且为了确保良好的延迟,不应该与应用程序日志或其他的操作系统文件系统活动共享用于Kafka数据的相同驱动器。您可以将这些驱动器RAID成单个卷或格式,并且把每个驱动器挂载到它自己的目录。Kafka的副本冗余功能可以由RAID或者应用程序级别提供,可以折衷选择实现。如果您配置了多个数据目录,那么分区将被循环分配到数据目录。每个分区只属于一个数据目录,如果分区间的数据不均衡,则可能导致磁盘间的负载不均衡。
RAID可以更好地平衡磁盘之间的负载(尽管似乎并不总是如此),因为它在较低的级别上进行平衡负载。 RAID的主要缺点是通常会大幅度影响写入性能并且降低可用磁盘空间。
RAID的另一个潜在好处是能够容忍磁盘故障。 然而,我们的经验是,重建RAID阵列是I/O密集型操作以至于服务器不可用,所以这不提供太多的实际可用性改进。
应用程序 vs. OS 刷新管理
Kafka总是立即将所有数据写入文件系统,并支持配置刷新策略的功能,该策略控制何时将数据从OS缓存中强制刷新到磁盘上。该刷新策略可以控制在一段时间之后或者在写入一定数量的消息之后把数据持久化到磁盘。这里有几个可选配置项。Kafka最总必须调用fsync指令才能知道数据已经被刷新。当从任何不被fsync所知的日志段崩溃中恢复时,Kafka将通过每个消息的CRC来检查其完整性,并且在启动时执行的恢复过程中会重建相应的偏移量索引文件。
请注意,Kafka中的持久性并不需要将数据同步到磁盘,因为失败的节点将始终从其副本中恢复。
我们建议使用完全禁用应用程序fsync的默认刷新设置。这意味着依靠操作系统和Kafka自己的后台完成的刷新操作。这种设置对大多数用途是最好的选择:无需调整,巨大的吞吐量和延时,以及完全的恢复保证。我们认为通过复制提供的保证比同步到本地磁盘更好,但是一些偏执的人仍然可能喜欢让OS,Kafka和应用程序级别的fsync策略都得到支持。
使用应用程序级别刷新设置的缺点是它的磁盘使用模式效率低下(它是操作系统在重新排序时没有什么回旋余地),并且在大多数Linux文件系统block中fsync写入文件时会引入延时,而后台刷新则会做更多粒度的页面级锁定。
通常你不需要对文件系统进行任何低级别的调整,但是,在接下来的几节中,我们也会介绍其中的一些内容,以防万一。
理解Linux操作系统刷新行为
在Linux中,写入文件系统的数据在pagecache中保存,直到必须写入磁盘(由于应用程序级别的fsync或操作系统自己的刷新策略)。数据的刷新是通过一组叫做pdflush的后台线程来完成的(或者在2.6.32内核中的“flusher threads”)。pdflush有一个可配置的策略,可以控制在缓存中可以维护多少脏数据,以及多久时间之前必须将数据写回到磁盘。 该策略详情请参阅这里。 当Pdflush无法跟上数据写入的速率时,最终会导致写入过程阻塞发生写入延时来减慢数据的堆积。
您可以通过执行下面命令来查看当前OS内存使用状态
> cat /proc/meminfo这些值的含义在上面的链接中有描述。
相对于进程内缓存,使用 pagecache 来存储将被写入到磁盘的数据有几个优势:
- I/O 调度器将一批连续的小写入转换成为更大的物理写入,从而提高吞吐量。
- I/O调度器将尝试重新排序写入操作,以尽量减少磁盘磁头的移动,从而提高吞吐量I/O
- 它会自动使用机器上的所有可用内存
文件系统的选择
Kafka在磁盘上使用常规的文件,不依赖于特定的文件系统。 然而,使用最多的两个文件系统是EXT4和XFS。 从历史上看,EXT4使用更多,但最近对XFS文件系统的改进已经表明它对Kafka的负载具有更好的性能,而且不会影响稳定性。
通过尝试各种文件系统的创建和挂载选项,在具有重要消息负载的集群上执行对比测试。Kafka监测的主要指标是“Request Local Time”,它表示追加操作的时间。XFS的本地时间更短(160ms比250ms +最好的EXT4配置),以及更低的平均等待时间。 随着磁盘性能变化,XFS的性能也表现出较小的波动。
一般文件系统注意事项
对于用于数据目录的任何文件系统,在Linux系统上,建议在挂载时使用以下选项:- noatime:此选项禁止在读取文件时更新文件的atime(上次访问时间)属性。 这可以消除大量的文件系统写入,特别是在引导consumer的情况下。 Kafka根本不依赖atime属性,因此禁用这个属性是安全的。
XFS 注意事项
XFS文件系统具有大量的自动调整功能,因此无需在文件系统创建时或挂载时对默认设置进行任何更改。 唯一值得考虑的调整参数是:- largeio: 这会影响统计调用报告的首选I/O大小。 虽然这可以允许在更大的磁盘写入时获得更高的性能,但是实际上它对性能的影响很小或者没有影响。
- nobarrier: 对于具有 battery-backed cache 的底层设备,此选项可以通过禁用定期写入刷新来提供更多的性能。 但是,如果底层设备运行良好,则会向文件系统报告不需要刷新,此选项不起作用。
EXT4 注意事项
EXT4是Kafka数据目录的文件系统的一个可选择的选项,但是为了获得最高的性能需要调整几个挂载选项。 另外,这些选项在故障情况下通常是不安全的,并且会导致更多的数据丢失和损坏。 对于单个 broker 失败,这不是一个问题,因为可以擦除磁盘,并从集群重建副本。 但在诸如停电等多故障情况下,这可能意味着不容易恢复损坏的底层文件系统(数据)。 以下选项可以调整:- data=writeback:Ext4默认为data = ordered,这会导致某些写入操作上有很强的顺序性。Kafka不需要这样的顺序,因为它在所有未刷新的日志上进行非常偏执的数据恢复。此设置消除了排序约束,似乎显著减少了延迟。
- Disabling journaling: Journaling 是一个折衷:在服务器崩溃之后,它会使重新启动更快,但会引入大量额外的锁定,从而增加写入性能的差异。那些不关心重启时间,想要减少写入延迟尖峰的主要来源,可以完全关闭Journaling。
- commit=num_secs: 这调整了ext4向其元数据日志提交的频率。将其设置为较低的值可以减少崩溃期间未刷新数据的丢失。将其设置为更高的值则将提高吞吐量。
- nobh: 当使用 data=writeback 模式时,此设置控制额外的排序保证。 Kafka应该是安全的,因为我们不依赖写入顺序并提高吞吐量和延迟。
- delalloc: 延迟分配意味着文件系统避免分配任何 block 直到物理写入发生。这使得ext4可以在很大程度上分配连续区域而不是较小的页面,并有助于确保数据连续写入。这个功能非常适合吞吐量。它似乎涉及到文件系统中的一些锁定,这增加了一些延迟差异。