PostgreSQL 用户常常发现,服务端在连接数较大的状况下,会呈现零碎内存耗费过多的状况,严重者可能会造成 OOM。然而服务端配置的共享内存(shared_buffers,wal_buffers 等)是肯定的,为什么内存会继续减少呢?这就与 PostgreSQL 的多过程架构无关了,上面咱们来剖析下。
1. 大规格 PG 实例内存使用率较高剖析
为了保障物理内存能失去充沛的利用,防止内存空间节约,Linux 把过程以后应用的内存局部加载到物理内存里,而不应用的局部则暂不加载。PostMaster 过程注册共享内存时,零碎只是调配一个虚构的地址空间,并不间接调配物理内存。当有理论的内存拜访时,CPU 才会将虚构地址映射到物理内存的一个地址上。保护这个映射关系的就是 PageTable,它负责将虚拟内存地址转换成物理内存地址。
Linux 的内存治理采取的是分页存取机制:把较大的物理内存分为了一个个固定大小(4kB)的内存页进行治理。每块内存页通过 PageTable 中的一个元组来保护虚构 / 物理内存之间的映射。CPU 为了进步虚构 / 物理内存之间的转换效率,也会在 TLB 中缓存一定量的 Page Table 元组。
对于 PostgreSQL 这种多过程架构程序来说,当服务端应用的共享内存较大,且并发连接数较多时,因为操作系统对于每个过程都要保护独自的内存映射,PageTable 中的元组数目将会变得十分多,所占用的内存大小也会特地大。
2. Huge Page 改善措施
Linux 为了应答这种场景,升高多过程下 PageTable 的内存耗费。自从 2.6 及以上内核版本提供了内存页大小为 2MB 的治理形式,称为 Huge Page。如果应用 Huge Page 的话,雷同物理内存使用量的状况下内存页的数目变少,缩小了 PageTable 元组的条目个数,从而升高了零碎的内存占用。
作为世界上最先进的开源数据库,PostgreSQL 也适配了 Linux 的 Huge Page 个性,服务端在注册共享内存时,会通过配置参数 huge_pages 来决定是否申请大页内存。
postgresql.conf:
huge_pages = on -- 注册共享内存时必须应用大页
huge_pages = try -- 注册共享内存时首先思考大页,若零碎提供的大页内存不足时,则全副应用一般页
huge_pages = off -- 注册共享内存时不应用大页
实在利用场景:某 PG 用户将实例(shared_buffers = 64GB)部署在一台内存为 256GB 的 ECS 上,业务忙碌时 ECS 内存使用率为 85%,PageTable 占用内存 120GB。而开启 Huge Page 后雷同业务场景的内存使用率升高到 50% 以下,PageTable 大小仅 300M!
3. PG 实例开启 Huge Page 操作步骤
(1)查看操作系统的 Huge Page 大小 grep Hugepage /proc/meminfo
(2)估算 PostgreSQL 实例须要的 Huge Page 使用量:128GB/2MB * 1.2 = 78643
(3)/etc/sysctl.conf 中增加:vm.nr_hugepages = 78643
(4)从新加载系统配置参数:sysctl –p
(5)确认是否配置胜利。能够看到 Huge Page 总数为 78643
(6)确认 PG 配置文件关上 huge_pages
(7)启动 PostgreSQL 服务端,能够看到零碎中的闲暇 Huge Page 曾经缩小,局部大页曾经被共享内存应用。
4. Huge Page 应用倡议
尽管 Huge Page 在肯定场景下能够改善服务端内存应用过高的状况,但不是激励所有的 PG 实例都应用大页,自觉的开启 Huge Page 可能引起服务端的性能降落。上面咱们依据 Huge Page 的优缺点来剖析下应用场景。
Huge Page 劣势:
(1)CPU 的 TLB 能够缓存的物理地址空间更大,从而晋升 TLB 的命中率,升高 CPU 负载;
(2)Huge Page 应用的内存是不可替换(swap)的,没有内存空间换入 / 换出的开销;
(3)极大的缩小了系统维护 PageTable 的内存开销。
Huge Page 劣势:
(1)Huge Page 应用的内存须要事后调配;
(2)Huge Page 应用固定大小的内存区域,不会被开释;
(3)对于写密集型的场景,Huge Page 会加大 Cache 写抵触的产生概率。
所以强烈推荐 PG 实例开启 Huge Page 的场景:共享内存应用较大(>=8GB)且连接数较多(>= 500),并且热点数据扩散。不举荐 PG 实例开启 Huge Page 的场景:写业务密集,热点数据集中且内存应用较小。
5.PG 开启 Huge Page 时的注意事项
(1)当配置参数 huge_pages 设置为 on 时,若 PG 启动时须要注册的共享内存大于操作系统提供的 Huge Page 大小时,数据库将无奈启动。举荐将 huge_pages 参数设置为 try,在此种场景下,PostMaster 将会改为申请一般内存。
(2)批改 shared_buffers/wal_buffers 等共享内存相干的 GUC 参数时,须要从新计算操作系统所需的 Huge Page 数,以防服务端无奈启动或者局部大页内存没有被应用且无奈开释而造成节约。
点击关注,第一工夫理解华为云陈腐技术~