page fault带来的性能问题

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: Linux进程如何访问内存 Linux下,进程并不是直接访问物理内存,而是通过内存管理单元(MMU)来访问内存资源。原因后面会讲到。 为什么需要虚拟内存地址空间 假设某个进程需要4MB的空间,内存假设是1MB的,如果进程直接使用物理地址,这个进程会因为内存不足跑不起来。既然进程不是直接访问

Linux进程如何访问内存

Linux下,进程并不是直接访问物理内存,而是通过内存管理单元(MMU)来访问内存资源。
原因后面会讲到。

为什么需要虚拟内存地址空间

假设某个进程需要4MB的空间,内存假设是1MB的,如果进程直接使用物理地址,这个进程会因为内存不足跑不起来。
既然进程不是直接访问物理内存,那么进程中涉及的内存地址当然也不是物理内存地址。
而是虚拟的内存地址,虚拟的内存地址和物理的内存地址之间保持一种映射关系,这种关系由MMU进行管理。
每个进程都有自己独立的虚拟地址空间。

什么是MMU

MMU_principle_updated
MMU全称是内存管理单元,它将物理内存分割成多个pages,MMU管理进程的虚拟地址空间中的PAGE和物理内存中的PAGE之间的映射关系。
因为是映射,所以随时都可能发生变化,例如某个进程虚拟内存空间中的PAGE1,在不同的时间点,可能出现在物理内存中的不同位置(当发生了页交换时)。

什么是page fault

当进程访问它的虚拟地址空间中的PAGE时,如果这个PAGE目前还不在物理内存中,此时CPU是不能干活的,
Linux会产生一个hard page fault中断。
系统需要从慢速设备(如磁盘)将对应的数据PAGE读入物理内存,并建立物理内存地址与虚拟地址空间PAGE的映射关系。
然后进程才能访问这部分虚拟地址空间的内存。

page fault 又分为几种,major page fault、 minor page fault、 invalid(segment fault)。

major page fault也称为hard page fault, 指需要访问的内存不在虚拟地址空间,也不在物理内存中,需要从慢速设备载入。从swap回到物理内存也是hard page fault。

minor page fault也称为soft page fault, 指需要访问的内存不在虚拟地址空间,但是在物理内存中,只需要MMU建立物理内存和虚拟地址空间的映射关系即可。
(通常是多个进程访问同一个共享内存中的数据,可能某些进程还没有建立起映射关系,所以访问时会出现soft page fault)

invalid fault也称为segment fault, 指进程需要访问的内存地址不在它的虚拟地址空间范围内,属于越界访问,内核会报segment fault错误。

什么是进程的working set

进程的working set是指当前在物理内存中,属于该进程的pages组成的集合。
这个集合中的page数随着系统的运行,可能扩大也可能缩小。
扩大working set是指进程正在访问更多的内存时。
缩小working set是指其他进程正在访问更多的内存,并且整个物理内存的空间不足,需要将某些干净的内存页free掉或者一些脏的内存页swap到交换分区去,如果这个操作设计到当前进程,对当前进程来说就是shrink working set。
缩小working set需要遵循lru (内核的内存老化)算法,并不是随便挑选PAGE进行shrink的。

什么是swap

swap和前面提到的shrink working set有关,如果是干净页(即从读入虚拟地址空间后,没有修改过的页),则直接标记为free,不需要写盘,也不会发生swap。
如果是脏页,那么它需要写盘,或者需要swap 到交换分区。

如何优化swap

建议使用IOPS和读写带宽很高的盘作为SWAP分区,例如PCI-E SSD。

什么时候需要加内存

如果你发现经常发生swap in , out。
说明进程的脏页被换出到swap后,紧接着这些页可能又需要被进程访问,从而这些页需要从swap写入物理内存,发生了hard page fault。
这种情况下,你就需要加内存了,确实是内存不够用了。
hard page fault非常损耗性能,因为发生page fault时,是需要等待的,而且IO通常来说都是比较慢的,容易成为性能瓶颈。

什么是oom, 为什么会发生OOM

前面讲到了shrink working set,是指系统在内存调度时,使用的一种手段,尽可能的让系统能使用有限的内存资源,支撑更多的并发任务。
oom是指系统已经没有足够的内存给进程使用,即能free的都已经free了,能swap out的也已经swap out了,再也不能挤出物理内存的情况。
如果遇到这种情况就会发生OOM,表示系统内存以及不足,Linux会挑选并KILL一些进程,来释放内存。

Linux page相关统计信息

sar

       -B     Report paging statistics.  The following values are displayed:

              pgpgin/s
                     Total number of kilobytes the system paged in from disk per second.

              pgpgout/s
                     Total number of kilobytes the system paged out to disk per second.

              fault/s
                     Number of page faults (major + minor) made by the system per second.  This is not a count of page faults that generate I/O, because some page faults can be resolved without I/O.

              majflt/s
                     Number of major faults the system has made per second, those which have required loading a memory page from disk.

              pgfree/s
                     Number of pages placed on the free list by the system per second.

              pgscank/s
                     Number of pages scanned by the kswapd daemon per second.

              pgscand/s
                     Number of pages scanned directly per second.

              pgsteal/s
                     Number of pages the system has reclaimed from cache (pagecache and swapcache) per second to satisfy its memory demands.

              %vmeff
                     Calculated as pgsteal / pgscan, this is a metric of the efficiency of page reclaim. If it is near 100% then almost every page coming off the tail of the inactive list is being reaped. If it gets too  low  (e.g.
                     less than 30%) then the virtual memory is having some difficulty.  This field is displayed as zero if no pages have been scanned during the interval of time.

一些CASE

.1. 如果PostgreSQL 设置了非常大的shared buffer, 为什么会有一段性能低潮(指全力压测时,平时估计感觉不到)
在PostgreSQL shared buffer设得非常大的情况下,Shared buffer作为进程的虚拟地址空间中的一部分,刚启动时这些虚拟地址空间还没有在物理内存中,所以填充过程中会发生page fault,性能较低。
当shared buffer被快速填满后,page fault减少,性能会上来。
例如在压测持续高并发的COPY数据入库时,看这个case https://yq.aliyun.com/articles/8528
在前面几百GB,page fault较多,产生较多的中断(这个case是软的,因为是在shared buffer中进行extend block,么有落盘),性能比shared buffer填满后有一定的差异。
240GB shared buffer,
shared buffer 填满前,2.8GB/s 导入速度

12:13:46 AM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
12:13:47 AM      8.08 1699410.10  40058.59      0.00 142064.65 137696.97      0.00 137632.32     99.95
12:13:48 AM     15.84 1634396.04  38605.94      0.00 412391.09 411564.36      0.00 411627.72    100.02

 22  44  33   0   0   0|  32k 2763M| 239B  364B|   0     0 | 184k  335k
 22  44  34   0   0   0|  12k 2791M| 120B  544B|   0     0 | 184k  336k
 22  45  33   0   0   0|  12k 2768M| 471B 1198B|   0     0 | 185k  341k
 22  44  33   0   0   0|  16k 2764M| 210B  454B|   0     0 | 183k  336k
 22  44  34   0   0   0|  16k 2777M| 239B  364B|   0     0 | 185k  341k

shared buffer 填满后, 4.7GB/s导入速度

12:14:40 AM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
12:14:41 AM     16.33 2831730.61    823.47      0.00 735045.92 725126.53      0.00 724985.71     99.98
12:14:42 AM     12.00 2760160.00    743.00      0.00 738037.00 728352.00      0.00 728370.00    100.00
12:14:43 AM     11.88 2751279.21    326.73      0.00 720171.29 715310.89      0.00 715374.26    100.01
12:14:44 AM     20.00 2788468.00    338.00      0.00 727221.00 720480.00      0.00 720480.00    100.00
12:14:45 AM     12.50 2858970.83    425.00      0.00 753507.29 740266.67      0.00 740166.67     99.99

 24  18  56   0   0   1|  28k 4703M| 120B  364B|   0     0 | 366k  655k
 24  18  57   0   0   1|  16k 5031M| 892B  994B|   0     0 | 382k  690k
 24  19  56   0   0   0|  12k 4833M| 120B  364B|   0     0 | 374k  672k
 24  19  56   0   0   1|8192B 4737M| 239B  544B|   0     0 | 371k  668k
 24  19  56   0   0   1|  20k 4826M| 120B  454B|   0     0 | 375k  674k

参考

目录
相关文章
|
监控 调度 开发工具
IO神器blktrace使用介绍
## 前言 1. blktrace的作者正是block io的maintainer,开发此工具,可以更好的追踪IO的过程。 2. blktrace 结合btt可以统计一个IO是在调度队列停留的时间长,还是在硬件上消耗的时间长,利用这个工具可以协助分析和优化问题。 ## blktrace的原理 一个I/O请求的处理过程,可以梳理为这样一张简单的图: ![](http://image
20564 0
|
缓存 Linux 调度
CPU 隔离:Nohz_full
SUSE Labs 团队探索了 Kernel CPU 隔离及其核心组件之一:Full Dynticks(或 Nohz Full),并撰写了本系列文章.
1903 0
CPU 隔离:Nohz_full
|
8月前
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。
|
消息中间件 存储 Java
Kafka核心知识点整理,收藏再看!
Kafka核心知识点整理,收藏再看!
289 3
Kafka核心知识点整理,收藏再看!
|
存储 NoSQL Linux
《探索 Linux 命令:systemd-coredumpctl》
**《systemd-coredumpctl概览》** `systemd-coredumpctl`, Linux中管理&分析core dump的利器。集中管控systemd生成的转储,详述crash细节。用`--list`查看所有转储,`--info <ID>`深入单一转储。需注意权限、存储管理,配gdb深化分析。精通此命令,加速问题诊断。#LinuxTips #CoreDumpAnalysis
|
存储 监控 Linux
在Linux中,如何查看和管理Linux系统日志?
在Linux中,如何查看和管理Linux系统日志?
|
存储 消息中间件 运维
分层存储救不了Kafka
Apache Kafka,作为流处理领域的标杆,面临云环境下的挑战,如高存储成本、运维复杂性和性能瓶颈。传统的本地磁盘Shared Nothing架构导致这些问题,而分层存储仅部分缓解,未根本解决问题。直接写入S3虽降低成本,但牺牲了延迟。为解决这些痛点,提出了创新的共享存储架构,通过EBS+S3实现存算分离,保持低延迟并提高弹性,同时降低成本和运维复杂性。该架构将EBS视为共享存储,实现Broker与存储的解耦,确保在云时代引领流处理系统的发展。
421 3
分层存储救不了Kafka
|
Linux 测试技术 调度
Linux调度器何时需触发抢占?—— 从hackbench谈起
作者:何惟禹 吴一昊一、背景:性能之战“不服跑个分”虽然已经沦为手机行业的调侃用语,但在操作系统领域仍然是最重要的评价方式之一。本文的故事也源于一次 Alinux3 与 CentOS8 的一次跑分的较量。当然比分较量并不是目的,更重要的是发现存在的回归缺陷并进行修复,最终让 Alinux3 全方位持平或超过 CentOS8。在本次较量中,我们使用 hackbench 作为跑分软件,我们在测试过程中
3063 0
Linux调度器何时需触发抢占?—— 从hackbench谈起
|
SQL 关系型数据库 数据库
PostgreSQL 如何潇洒的处理每天上百TB的数据增量
本文主要介绍并测试一下PostgreSQL 在中高端x86服务器上的数据插入速度,帮助企业用户了解PostgreSQL在这种纯插入场景的性能。(例如运营商网关数据,金融行业数据,产生量大,并且要求快速插入大数据库中持久化保存。) 测试结果写在前面:每32K的block存储89条记录, 每条记录约3
40152 131