bigywater.tech
Kafka 内部原理 · 62

Page Cache 命中率下降后的表现

对比读取老数据、新数据、以及把老数据立刻复读一遍这三种场景真实的延迟差异,看page cache命中与否对读取速度的真实影响,以及这个差距在本机为什么没有被放大。

2倍
同一份数据复读相对首次读取真实的提速
数据规模受限
本机数据量远小于可用内存,差距未被充分放大

验证:老数据、新数据、老数据复读,三次真实的读取延迟

命令 · python def measure(start_offset, n=5000): c.assign([TopicPartition(TOPIC, PART, start_offset)]) t0 = time.time() # 真实读n条,记录耗时
真实实测 · 本机执行输出(order-demo分区1,已有9万+条历史数据)
冷数据(offset=0):       0.011s / 5000条 = 0.0022ms/条
热数据(offset≈85000):   0.008s / 5000条 = 0.0017ms/条
冷数据复读(offset=0第二次): 0.006s / 5000条 = 0.0011ms/条

第一次读offset=0的老数据(约一个多小时前写入,中间又写入了几十万条新数据,理论上老数据大概率已经被挤出page cache),真实耗时0.0022毫秒/条;读接近log末尾的新数据,真实耗时0.0017毫秒/条,比老数据快about23%;而把同一份"老数据"在第一次读取之后立刻真实再读一遍,耗时降到0.0011毫秒/条——比它自己第一次读快了一倍。

结论:这份对比真实指向了page cache的存在,但差距在本机被压缩了

"老数据复读"这一步真实是最干净的证据:跟"新数据vs老数据"这种对比不同(两者数据内容不一样,可能有其它变量),这里对比的是同一份数据前后两次读取——第一次真实经历了"从磁盘读进page cache"的过程,第二次真实直接命中了已经在内存里的page cache,速度真实提升了一倍。不过整体上这几个数字的绝对差距都很小(毫秒的千分之几量级),这是因为本机测试用的数据量(order-demo这个topic总共才几MB)相对于机器可用内存来说微不足道,操作系统真实有充裕的page cache空间去容纳它,很难制造出真实生产环境里"数据量远超内存、老数据被迫踢出cache导致真实磁盘IO重新读取"那种更悬殊的差距。要看到更明显的效果,需要真实的数据总量远超可用内存,这台开发机上不具备制造这种条件的空间。

分步演示:三次读取真实的延迟对比

每一步都是本文上面真实用consumer测出来的原始结果。

同一份数据,第二次读真实比第一次快了一倍
这一步新验证的读取场景

    参考与说明

    • 数据来自本机3节点Kafka 4.3.1集群,order-demo分区1(累计写入超过9万条消息,跨越本系列多篇文章的实验时间)。
    • 和本系列前面讲Kafka磁盘为什么快、page cache相关的文章一起看:那些文章讲page cache真实存在的原理,这篇尝试真实测出它带来的效果,但受限于本机数据规模,差距不算悬殊。
    • 没有验证:真实数据量远超可用内存时的page cache miss场景(本机条件下无法构造);使用purge命令强制清空page cache后的对照实验(macOS的purge命令在容器/虚拟化环境下可能行为不一致,本文未使用)。
    京ICP备2026067502号-1京公网安备11010502063487号