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

时间:2018-02-04 15:52:59

标签: apache-kafka kubernetes cgroups page-caching

我一直在Kubernetes上运行Kafka,暂时没有任何重大问题;然而,我最近推出了一系列Cassandra pods并开始遇到Kafka的性能问题。

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

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

在Kafka中,更多页面错误会导致更多磁盘写入,这会妨碍顺序IO的优势并降低磁盘性能。如果您使用AWS的EBS卷,这最终会耗尽您的突发平衡并最终导致整个群集发生灾难性故障。

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

1 个答案:

答案 0 :(得分:5)

我认为这是一个有趣的问题,所以这是从一些挖掘中发现的一些调查结果。

最佳猜测: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-created-cassandra-3948-sequentialwriter-doesnt-fsync-before-posix-fadvise

最近(2017年1月)还有一些研究来自三星补丁Cassandra和内核中的fadvise以更好地利用多流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 over cassandra或反之亦然)和特定IO配置(专用与共享设备),可以使用特定的调优模型,这些可以被概括为政策模型。