如何在 Kubernetes 中运行 Kafka 时管理页面缓存资源



我一直在 Kubernetes 上运行 Kafka,没有任何重大问题;然而,我最近引入了一个 Cassandra pod 集群,并开始遇到 Kafka 的性能问题。

尽管 Cassandra 不像 Kafka 那样使用页面缓存,但它确实会频繁写入磁盘,这可能会影响内核的底层缓存。

我知道 Kubernetes pod通过 cgroups 管理内存资源,可以通过在 Kubernetes 中设置内存请求和限制来配置,但我注意到 Cassandra 对页面缓存的利用会增加我的 Kafka pod 中的页面错误数量,即使它们似乎没有竞争资源(即,它们的节点上有可用的内存)。

在 Kafka 中,更多的页面错误会导致更多的磁盘写入,这阻碍了顺序 IO 的好处并损害了磁盘性能。如果您使用 AWS 的 EBS 卷之类的东西,这最终会耗尽您的突增余额,并最终导致集群中的灾难性故障。

我的问题是,是否可以在 Kubernetes 中隔离页面缓存资源,或者以某种方式让内核知道我的 Kafka pod 拥有的页面应该比我的 Cassandra pod 中的页面在缓存中保存的时间更长?

我认为这是一个有趣的问题,所以这是一些挖掘发现的帖子。

最佳猜测:k8s OOB 无法做到这一点,但有足够的工具可用,因此它可以成为研究和开发可以部署为 DaemonSet 的调优和策略应用程序的富有成效的领域。

发现:

应用程序可以使用 fadvise() 系统调用向内核提供指导,说明应用程序需要哪些文件支持的页面,哪些页面不需要并且可以回收。

http://man7.org/linux/man-pages/man2/posix_fadvise.2.html

应用程序还可以使用 O_DIRECT 来尝试避免在执行 IO 时使用页面缓存:

https://lwn.net/Articles/457667/

有迹象表明,Cassandra已经以一种试图优化以减少其页面缓存占用量的方式使用fadvise:

http://grokbase.com/t/cassandra/commits/122qha309v/jira-创建-Cassandra-3948-sequentialwriter-don't-fsync-before-posix-fadvice

三星最近(2017 年 1 月)也有一些研究在内核中修补 Cassandra 和 f建议,以更好地利用多流 SSD:

http://www.samsung.com/us/labs/pdfs/collateral/Multi-stream_Cassandra_Whitepaper_Final.pdf

Kafka 是页面缓存架构感知的,尽管它似乎没有直接使用 fadvise。内核中可用的旋钮足以在专用主机上调整 Kafka:

  • vm.dirty* 提供有关何时将写入(脏)页面放回磁盘的指导
  • vm.vfs_cache_pressure有关使用 RAM 进行页面缓存的激进程度的指导

内核中对特定于设备的写回线程的支持可以追溯到 2.6 天:

https://www.thomas-krenn.com/en/wiki/Linux_Page_Cache_Basics

Cgroups v1 和 v2 侧重于基于 pid 的 IO 限制,而不是基于文件的缓存调整:

https://andrestc.com/post/cgroups-io/

也就是说,旧的 linux-ftools 实用程序集有一个简单的命令行旋钮示例,用于对特定文件使用 fadvise:

https://github.com/david415/linux-ftools

所以那里已经足够了。给定特定的 kafka 和 cassandra 工作负载(例如,读取重与写重),特定的优先级(kafka 而不是 cassandra,反之亦然)和特定的 IO 配置(专用与共享设备),可能会出现特定的调优模型,这些可以推广到策略模型中。

最新更新