PostgreSQL中如何配置Huge page的数量

news2024/9/30 3:19:54

在了解如在PG中如何配置大页之前,我们先要对大页进行一定的了解,为什么要配置大页,配置大页的好处有哪些。

我们日常的操作系统中,程序不直接使用内存,而是使用虚拟内存地址来处理内存分配,避免计算的复杂性和物理地址映射到应用程序内存空间的复杂性。虚拟地址模型在应用程序读取或写入内存时立即将虚拟地址转换为相应的物理内存地址。这种映射结构存储在page tables中,这是一种分层组织的查找表。

如下图,在运行中的程序使用虚拟内存映射到物理内存

在这里插入图片描述

下图为虚拟内存通过page table映射到物理内存

在这里插入图片描述

地址转换依靠MMU实现,MMU是内存管理单元,是硬件设备,在CPU内部

在这里插入图片描述

如下图,使用MMU使用TLB的加速映射

在这里插入图片描述

下图说明了TLB的加速原理,如果物理地址在TLB中命中,直接转换为物理地址,只访问一次内存地址,否则扫描page table查找地址然后映射条目到TLB,然后再转换为物理地址,这样就有两次内存访问。最差的是page table也没有,需要从磁盘写到page table,那么这样效率会更慢。

在这里插入图片描述

因为TLB只能保存几千个条目,那么我们为了提高性能,可以有两个办法:
  • 增加TLB的大小,升本太高,受限硬件,提升有限
  • 增加内存page的大小,如果TLB只能对应512个页表项,那么能否每个page对应1G的内存呢,这样程序访问512G的内存,也能保证都利用到TLB缓存了。
如下图,4K,2MB,1GB在256GB内存下对应的页面数两

在这里插入图片描述

操作系统上的内存分配都是通过分配单个或多个可用内存页来完成的。这些页面都是特定大小,主要取决于操作系统。在Linux上,内存分配使用的默认页面大小是4kB。
因此,我们可以想象,分配大量内存需要在页表中保存大量页面,以便将它们映射到相应的物理地址。查找虚拟地址需要多次内存访问,与CPU速度相比,这是非常昂贵的。因此,现在的cpu维护一个叫Translation Lookaside Buffer (TLB)的缓存,TLB是一个加速虚拟内存和物理内存之间转换的缓存。

TLB的大小被限制在几千个条目,特别是在具有高内存特定内存工作负载的系统上,很快就会成为瓶颈。例如,像PostgreSQL这样的数据库使用共享缓存池来实现进程间通信(IPC)、块层访问和其他功能,这很快就会给TLB带来很大的压力,因为虚拟地址映射的数量是有限的。特别是共享缓冲池配置大内存(比如100GB的shared buffer)的时候,这些实例可能因此受到性能影响。

所以我们在内存很大的时候,比如有256G内存,可以设置huge page,提高效率。在x86系统上,我们通常可以设置2MB或1GB大小,IBM POWER允许64kB、16MB和16GB。
在x86架构中,配置大页时,默认的页面大小是2MB。可以通过/proc/meminfo获取你的系统当前设置:

cat /proc/meminfo | grep -i HugePage
AnonHugePages: 161792 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB

HugePages_Total为零表示目前没有配置大页面,因此HugePages_Rsvd,HugePages_Free和HugePages_Surp也都为零。Hugepagesize显示了内核中当前为大页面配置的默认大小。在稍后配置大页时,我们将会考虑如何设置这些值。

如下图,可以通过查看/proc/cpuinfo中的flages,是否支持各种大页的尺寸

在这里插入图片描述

PG中大页的使用

PostgreSQL中,只有shared buffer中可以使用大页来分配内存。而work_mem, maintenance_work_mem, autovacuum_work_mem这些动态内存的分配不会使用大页。此外,用于在并行查询工作之间传输数据和通信的动态共享内存段不会自动请求它们,但有一个例外,我将在下一段关于在Linux上为大型页面配置PostgreSQL的内容中描述。还需要在所谓的mmap段中分配共享缓冲区,这是由shared_memory_type参数控制的。这是Linux上的默认设置。系统V共享内存只被PostgreSQL用来初始化一个非常小的共享内存区域;缓冲池本身是通过mmap分配的。

对于Linux上的PostgreSQL,不推通过THP配置大页,因为它不会直接分配大页,而是在需要时提供给它们。THP是可切换的,与显式配置的大页相比,它被认为是一个较慢的选择。在这种情况下,FreeBSD等其他操作系统提供了更好的支持。

在PG15中,数据库关闭状态,可以通过命令直接计算需要大页大小,如下:

 su - postgres
 /usr/pgsql-15/bin/postgres --shared-buffers=20GB -D $PGDATA -C shared_memory_size_in_huge_pages
10475

PG中通过huge_pages参数配置是否开启大页
try:尝试分配大页,如果不能,则退回到正常的页面分配(目前的默认设置)
on:shared buffer强制使用大页
off:不使用大页

上面计算出需要设置的大页数后,可以通过修改文件来修改大页数量,注意只是临时修改吗,重启无效

 echo 10475 > /proc/sys/vm/nr_hugepages

再次查看大页设置:

grep -i hugepage /proc/meminfo
AnonHugePages:    124928 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:   10475
HugePages_Free:    10475
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

永久修改配置:

cat /etc/sysctl.d/01-nr-hugepages.conf
vm.nr_hugepages=10475

修改 postgresql.conf文件中以下参数

shared_buffers = 20GB
huges_pages = on
huge_page_size = 0 #use default kernel setting

PostgreSQL必须启动(或重新启动),并且应该通过默认的大页大小分配其共享缓冲池。查看/proc/meminfo信息。输出如下:

grep -i hugepage /proc/meminfo
AnonHugePages:    176128 kB
ShmemHugePages:        0 kB
FileHugePages:         0 kB
HugePages_Total:   10475
HugePages_Free:    10264
HugePages_Rsvd:    10264
HugePages_Surp:        0
Hugepagesize:       2048 kB

使用pmap工具可以查看postmaster进程分配的内存段

pmap  $(head -n1  /var/lib/pgsql/15/data/postmaster.pid) | grep huge
00007f11a5400000 21452800K rw-s- anon_hugepage (deleted)

在PostgreSQL如何使用大页面的一节中,我们应该解释一下那里提到的异常。通常,动态共享内存分配是有目的的,例如并行查询工作者处理并行查询时。默认情况下,这些动态分配的内存不是由mmap完成的,而是PostgreSQL在Linux上默认通过shm_open()使用posix API。在这种情况下,不分配大页。但是,在并行查询时,也会产生内存压力,特别是在需要处理大量数据时。

从版本14开始,PostgreSQL提供了参数min_dynamic_shared_memory。配置后,指定的值定义了在服务器启动时创建的共享内存中的额外空间,这些空间应该用于并行查询工作。由于它是与缓冲池一起分配的,因此它也使用了大页进行分配。我们可以扩展上面的例子,并重新计算设置2GB的额外共享内存,用于并行查询:

/usr/pgsql-15/bin/postgres -D $PGDATA --min-dynamic-shared-memory=2GB --shared-buffers=20GB -C shared_memory_size_in_huge_pages
11499

同样,需要停止PostgreSQL实例才能成功执行该命令。与前一个示例相比,现在要保留的大页面的数量增加了2GB。

如果PG版本低于15怎么办?

这些版本更难处理。特别是需要保留多少大页的计算比较麻烦。到目前为止,最好的解决方案就是手动启动PostgreSQL,设置huge_pages=on,然后调试参数。在这种情况下,如果不能分配请求的共享内存大小,PostgreSQL打印以下错误消息:

FATAL:  could not map anonymous shared memory: Cannot allocate memory
HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 21965570048 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
LOG:  database system is shut down

注意HINT部分,它告诉我们PostgreSQL想要分配21965570048字节的共享内存。这个值可以用来计算页面的数量。这个数字的问题是,当我们将共享缓冲区指定为20GB时,这比我们所要求的大一些。这是因为PostgreSQL还需要为其他内部进程(如wal_buffers或max_locks_per_transactions)提供额外的共享内存。扩展可能需要额外的共享
内存。PostgreSQL内部使用了一个近似如下的公式:

((shm size + (BLKSZ - (shm size % BLKSZ))) / (huge page size * 1024)) + 1 = num huge pages
#假设我们的数据库的BLKSZ是以8KB的page编译安装的
((21965570048 + (8192 - (21965570048 % 8192))) / (2048 * 1024)) + 1 = 10475
track_activity_query_size设置

另外要注意track_activity_query_size的设置,默认1024,如果超过,那么pg_stat_activity,pg_stat_statements中记录sql的长度会被截断。但是一定要注意,如果加大该设置,会分配max_connections * track_activity_query_size的内存来保存我们的语句。
在这里插入图片描述
如上所述,PostgreSQL使用共享内存来存储这些统计信息。PostgreSQL不能动态更改内存段的大小。因此,更改track_activity_query_size也需要重新启动PostgreSQL。所以在启用实例前,一定要考虑好如何设置该参数。另外还要注意,该参数设置大了,那么pg_stat_statements也会变大,可能也会影响系统性能,一定要注意定期使用该函数重置pg_stat_statements_reset

参考:
https://courses.teresco.org/cs432_f02/lectures/12-memory/12-memory.html
https://www.cybertec-postgresql.com/en/huge-pages-postgresql/
https://www.cybertec-postgresql.com/en/fixing-track_activity_query_size-in-postgresql-conf/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/804062.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++数据结构笔记(11)二叉树的#号创建法及计算叶子节点数

首先分享一段计算叶子节点数目的代码,如下图: 不难发现,上面的二叉树叶子节点数目为4。我们可以采用递归的方式,每当一个结点既没有左结点又没有右节点时,即可算为一个叶子结点。 int num0; //全局变量,代…

Linux--多个源文件编译成同一个可执行文件

写法一:不推荐 写法二、推荐 $:代表目标文件 $^:代表生成目标文件的所有源文件

收藏这11个插画网站,插画师必备!

无论是在哪种设计工作中,插画素材都是比较常用的素材。今天本文整理了11个好用的插画工具,能帮助设计师轻松绘制出插画,一起来看看吧! 1、即时设计 即时设计是一款国产的,省心省力的插画工具。它为设计师提供了简单易…

【Git】Git的概念安装工作区-暂存区-版本库

文章目录 Git概念-版本控制器Git安装Centos平台&ubuntu Git基本操作创建Git本地仓库配置Git 认识⼯作区、暂存区、版本库添加文件查看.git文件总结添加文件场景2 Git概念-版本控制器 引入 我们在编写各种⽂档时,为了防⽌⽂档丢失,更改失误&#xff0…

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作 基础半导体器件领域的高产能生产专家Nexperia(安世半导体)近日宣布与国际著名的为汽车行业提供先进电子器件的供应商 KYOCERA AVX Components (Salzburg) GmbH 建立合作关系&am…

【弹力设计篇】聊聊隔离设计

为什么需要隔离设计 隔离其实就是Bulkheads,隔板。在生活中隔板的应用主要在船舱中进行设计,目的是为了避免因一处漏水导致整个船都沉下去。可以将故障减少在一定的范围内,而不是整个船体。 从架构演变来说的话,大多数系统都是从…

兵兵数码:网络机顶盒哪个好?2023最新网络机顶盒排名

网络机顶盒让电视机重生,解决卡顿、资源少、广告多等问题,我们每年都会进行网络机顶盒测评,今年已经测评过17款,通过多角度对比筛选了五款表现最佳的产品整理成网络机顶盒排名,近期想买网络机顶盒不知道网络机顶盒哪个…

工具篇-Mysql 性能优化

文章目录 前言一、Mysql 性能问题:1.1 一条sql 的执行流程:1.2 MySQL 可能出现的性能问题: 二、优化:2.1 硬件层面:2.2 软件层面:2.2 .1 mysql 参数配置优化:2.2.1.1 mysql 服务端连接优化&…

【Golang】Golang进阶系列教程--为什么 Go 语言 struct 要使用 tags

文章目录 前言struct tags 的使用使用反引号避免使用空格避免重复使用标准化的 tag 名称多个 tag 值 struct tags 的原理struct tags 的优势常用的 struct tags参考文章: 前言 在 Go 语言中,struct 是一种常见的数据类型,它可以用来表示复杂…

【MMdetection3d】Step1:环境搭建

Step1:环境搭建 1.创建并激活虚拟环境1.1 用官方Pytorch指令安装!1.2 用官方mmcv指令安装! 2 安装MMDetection3 克隆编译mmdetection3d4 环境测试5 测试demo 在Conda虚拟环境中搭建MMdetection3d环境 1.创建并激活虚拟环境 conda create -n mm3d python…

JavaEE简单示例——在使用Tomcat的时候可能出现的一些报错

简单介绍: 在我们之前使用Tomcat的时候,经常会出现在启动的时候因为一些报错导致项目无法正常的启动,我们就对一些比较常见的报错来看一下可能导致的原因,以及出现报错之后如何去解决。 严重: Failed to initialize end point a…

Spring中最简单的过滤器和监听器

1. 过滤器概念引入 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功…

一文看完智能视频监控系统的工作原理及场景应用

智能视频监控系统的原理是利用摄像机采集视频信号,并通过相关的AI模型算法实时分析视频内容,提取出有用信息,如人脸、车牌号码、移动物体等,并进行识别及特征提取,最终形成监控报警、实时监控、历史录像回放等应用。 智…

【JAVA】 String 类简述笔记

个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 文章目录 前言String类创建一个String类 常用方法字符串长度 length() 方法连接字符串 concat() 方法创建格式化字符串 format()功能 前言 string是C、java、VB等编程语言中的字符串&…

项目报错clone2.weekday is not a fuction

ant-design-vue中的dayjs版本和我项目中的dayjs版本不一样 项目中的dayjs版本号 ant-design-vue中的dayjs版本号"dayjs": “^1.11.9” 解决方法: 将项目中的版本号更新"dayjs": “^1.11.9” yarn add dayjs^1.11.9

lc162.寻找峰值

由于题目假设nums[-1]和nums[n]等于负无穷 如果nums[i]>nums[i1]&#xff0c;即nums[-1]<nums[i]>nums[i1]&#xff0c;那么在[0,i]区间内一定存在峰值 如果nums[i]<nums[i1]&#xff0c;即nums[i]<nums[i1]>nums[n]&#xff0c;那么在[i1,n-1]区间内一定存…

dubbo原理框架设计

dubbo原理框架设计 &#xff08;1&#xff09;config 配置层&#xff1a;对外配置接口&#xff0c;以 ServiceConfig, ReferenceConfig 为中心&#xff0c;可以直接初始化配置类&#xff0c;也可以通过 spring 解析配置生成配置类。 &#xff08;2&#xff09;proxy 服务代理…

如何使用postman判断返回结果是否正确

针对一个接口&#xff0c;我们在知道参数以及参数对应的结果时&#xff0c;可以通过postman进行判断&#xff0c;验证返回数据是否与预期数据相等。这样可以使我们的接口测试更加的方便简洁。 1、准备数据。 postman可以接受的文件格式如图所示&#xff0c;一般来说可以将我们…

mysql(五)主从配置

目录 前言 一、MySQL Replication概述 二、MySQL复制类型 三、部署MySQL主从异步复制 总结 前言 为了实现MySQL的读写分离&#xff0c;可以使用MySQL官方提供的工具和技术&#xff0c;如MySQL Replication&#xff08;复制&#xff09;、MySQL Group Replication&#xff08;组…

【读点论文】PP-YOLOE: An evolved version of YOLO,面向友好部署的模型设计,为项目后续产业落地提供了更加有效的参考

PP-YOLOE: An evolved version of YOLO Abstract 在本报告中&#xff0c;我们介绍了PP-YOLOE&#xff0c;一种具有高性能和友好部署的工业最先进的目标探测器。我们在之前的PP-YOLOv2的基础上进行优化&#xff0c;采用无锚模式&#xff0c;更强大的骨干和颈部配备CSPRepResSt…