透明代码大页:让数据库也能用上 2MB 大页!

代码大页技术是一种优化内存访问延迟的方法,尤其适用于数据库系统。通过支持2MB大页,减少内存碎片和提高性能,文章探讨了代码大页与透明大页的区别,介绍了其在Mysql、PostgreSQL和OceanBase等数据库中的应用和性能评估。文章还提到了自适应代码大页,以解决x86平台上大页资源限制的问题,以及代码段优化的其他方法,如PGO和LTO。目前,代码大页已经在龙蜥操作系统和阿里云ECS上得到支持,并展示了潜在的未来发展方向。
摘要由CSDN通过智能技术生成

01 背景

大页技术是操作系统中优化内存访问延迟的一种技术,其优化原理与 CPU TLB 硬件有直接关系,而其优化效果不仅受 CPU TLB 硬件影响,还需要看应用访存特点。只考虑 Arm 和 x86 两种平台,已知的大页技术包括透明大页、hugetlbfs、16k 和 64k 全局大页。在合适的场景大页技术可以提升应用性能达 10% 以上,尤其是针对当前云上应用逐年增长的内存使用趋势,使用大页技术是其中重要的提升“性能-成本”比例的优化手段。透明大页(Transparent Huge Pages,THP)从 2011 年开始在 Linux 内核中已经支持起来,其通过一次性分配 2M 页填充进程页表,避免多次缺页开销,更深层次从硬件角度优化了 TLB 缺失开销,在最好情况下,对应用的优化效果达到 10% 左右。除以上优点外,透明大页(主要供堆栈使用)使用过度也会导致严重的内存碎片化、内存膨胀和内存利用率低等问题,这就是当前透明大页没有在数据库中使用的核心原因,只能感叹“卿本巧技,奈何有坑”。

代码大页在透明大页的基础上,将支持扩展到可执行二进制文件,包括进程二进制文件本身、共享库等可执行数据。与透明大页相比,由于代码大页仅将占比较低且有限的可执行文件页部分转换为大页,从根本上避开了内存碎片以及内存不足的问题。与此同时,由于代码类数据和普通堆栈数据访问热度对整体性能影响不同(主要指代码数据或堆栈数据访问缺页一次的性能影响),导致代码类数据使用大页所提升的性能远大于同样分量的透明大页。所以推广和完善代码大页相比透明大页更加简单和容易。

本文主要介绍我们的代码大页方案以及一些实验阶段性能测试。为了方便阅读,在这里简单归纳了一下 Linux 系统中大页的支持现状和和必要的数据库相关背景。

02 大页现状

当前 Linux 内核支持的大页包括 THP 和 hugetlb,其页大小分别是:

不考虑其他架构,在 x86 和 Arm 架构中,提到 THP,我们可以一股脑地认为其大小就是 2MB,当前内核暂时还不支持 1GB THP,技术上实现没有什么问题,社区隐隐约约也有人曾经发过相关补丁...。回到这里,Arm64 相比 x86,hugtlb 多两种大页支持,主要是 contiguous bit,该特性主要是针对 TLB entry 的优化(连续的 16 个 PTE/PMB,若其上的 PFN 也是连续的,cont bit 会将其使用的 16 个 TLB entry 优化仅占一个 TLB entry)。这里的 64KB 和 32MB 的由来就是 16*4KB 和 16*2MB。

另外,在全局页粒度的支持上,Arm64 也比 x86 更会玩,提供的 16KB (CONFIG_16KB 表示)和 64KB(CONFIG_64KB表示)两种选择,这两种页相比 4KB 页,在 TLB 和 cache 上都有明显的优化相关,从而优化宏观指标,当然也并非所有 benchmark 表现出性能提升,例如在 SPECjvm2008 和 stream 中,我们就发现有多项指标在使用 CONFIG_64KB 的时候有较严重的性能下降。除以上问题,还想再啰嗦一下,CONFIG_64KB 中,THP 的大小着实有点“吓人”,有 512MB。

因此,大伙对 16KB、64KB 还是又爱又恨。

03 Mysql、PostgreSQL 和 OceanBase

站在内存管理的角度,我们仅仅关心 Mysql、PostgreSQL 这些数据库用了多少内存、页缓存占多少、匿名页占多少以及代码段还有 iTLB/dTLB miss 到底高不高。当然还随便想知道 THP 有没有优化,下面几个是简单归纳的几点我们关系的数据库特点:

Mysql

  • Mysql 是一个多线程模式的数据库,其代码段大小一般 18M 左右。
  • THP 不敏感,打开 THP,大约仅有不到 3% 的性能提升。
  • 跨 NUMA 敏感,本地虚拟机 32 核验证跨 NUMA 抖动在 5~7% 左右。

PostgreSQL

  • 多进程模型,代码段大小大约 10M 左右。
  • 应用 iTLB-load-misses 较高,大约 1.41% 左右。

OceanBase

  • 多线程模型,代码段大小大约 200M~280M。
  • 一般独占单机使用,性能验证过程中并发数要求高:128、1000、1500。
  • THP 本地验证不敏感。

这些数据库大约至少有两个共同点:代码段大、iTLB Miss 高。本文也是基于这两个特征进行的优化,当然代码大页优化目标也不局限于这三种数据库。

04 代码大页

接着前面数据库背景介绍,这里直接开始代码大页方案。代码大页大致实现分为:整理结构、大致实现、填充功能简介还有最后的代码大页性能评估(包括 Mysql 和 PostgreSQL),最后是我们专门为解决 x86 平台设计的自适应功能。

4.1 整体结构与实现

基于透明大页异步整合大页(主要指 khugepaged 内核线程)的框架:

上图所展示的代码大页方案主要包括三个部分:

(1)映射首地址对齐(蓝色高亮):这个部分主要是在 elf binary 和 DSO 建立映射的过程中,优先考虑分配 2M 对齐的虚拟地址空间,便于映射到 2M 大页。

(2)异步 khugepaged 扫描整合以及加速(橙色高亮):与 THP 相似,单独设计用户态接口 hugetext_enabled 控制。复用 khugepaged 整合 2M 大页。此外,由于 hugetext 与 THP 共用 khugepaged,在 THP=always 时,也能整合部分符合条件的代码大页;关于加速部分,我们解决了在 THP 使能的场景中,代码段整合慢的问题,这也是我们改进 READ_ONLY_THP_FOR_FS 带来的挑战之一。

(3)DSO写回退(紫色高亮):对于 DSO 所建立的映射,内核屏蔽了 MAP_DENYWRITE,导致用户态可以写打开共享库文件(尽管一旦对该共享库写,进程多数情况会 core dump)。针对这种情况,在检测到该共享库存在写者时,对其 pagecache 进行清空;DSO 为什么有这么多顾虑可以跳转:https://developer.aliyun.com/article/863760

注意:首地址 2M 对齐的本意是 mmap addr = mmap pgoff (mod 2M),由于 elf binary 和 DSO 的可执行 LOAD 段的 pgoff 一般为 0,这里为了叙述方便,我们简称地址 2M 对齐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值