本篇文章着眼于 Linux 页面大小对数据库性能的影响,以及如何优化数据库 Kubernetes 节点。
Linux 内存管理模型非常直接明了,因为 Linux 的这种机制使其具有可移植性并且能够在内存管理单元相差不大的机器下实现 Linux,下面我们就来认识一下 Linux 内存管理是如何实现的。
内存管理是Linux系统重要的组成部分。为了解决内存紧缺的问题,Linux引入了虚拟内存的概念。为了解决快速存取,引入了缓存机制、交换机制等。
vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。
传统的存储设备例如HDD,SSD,nvme,SAN LUNS等以blocks为单位提供存储功能。Block以字节为单位的可寻址存储单元。传统的硬盘的block大小是512字节。Newer设备通常是4K或者8K,但也可以选择逻辑/模拟的512字节的block。
内存是计算机的重要资源,虽然今天大多数的服务对内存的需求都没有那么高,但是数据库以及 Hadoop 全家桶这些服务却是消耗内存的大户,它们在生产环境动辄占用 GB 和 TB 量级的内存来提升计算的速度,Linux 操作系统为了更好、更快地管理这些内存并降低开销引入了很多策略,我们今天要介绍的是 HugePages,也就是大页[^1]。
在 Linux 下 free 命令可以看出系统当前内存状况,附上 -k , -m , -g 可以分别输出对应单位的内存状况:
缓冲区是所有 I/O 的基础,I/O 讲的无非就是把数据移进或移出缓冲区;进程执行 I/O
对 Linux 稍有了解的人都知道,Linux 会将物理的随机读取内存(Random Access Memory、RAM)按页分割成 4KB 大小的内存块,而今天要介绍的 Swapping 机制就与内存息息相关,它是操作系统将物理内存页中的内容拷贝到硬盘上交换空间(Swap Space)以释放内存的过程,物理内存和硬盘上的交换分区组成了操作系统上可用的虚拟内存,而这些交换空间都是系统管理员预先配置好的[^1]。
本文旨在深入探讨Linux操作系统的虚拟内存管理机制。我们将从基本概念开始,逐步深入到内核级别的实现细节。为了达到这个目标,本文将结合理论讨论和实际的代码分析。我们希望通过这种方式,使读者对Linux虚拟内存管理有更深入的理解。
Linux 内存管理模型不是咱们这个系列的讨论重点,我们这里只会简单提一些对于咱们这个系列需要了解到的,如果读者想要深入理解,建议大家查看 bin 神(公众号:bin 的技术小屋)的系列文章:一步一图带你深入理解 Linux 虚拟内存管理
前面提到了虚拟内存需要映射物理内存才能使用,这个映射关系被保存在内存中的页表(Page Table)。现代 CPU 架构中一般有 TLB (Translation Lookaside Buffer,翻译后备缓冲,也称为页表寄存器缓冲)存在,在里面保存了经常使用的页表映射项。TLB 的大小有限,一般 TLB 如果只能容纳小于 100 个页表映射项。 我们能让程序的虚拟内存对应的页表映射项都处于 TLB 中,那么能大大提升程序性能,这就要尽量减少页表映射项的个数:页表项个数 = 程序所需内存大小 / 页大小。我们要么缩小程序所需内存,要么增大页大小。我们一般会考虑增加页大小,这就大页分配的由来,JVM 对于堆内存分配也支持大页分配,用于优化大堆内存的分配。那么 Linux 环境中有哪些大页分配的方式呢?
现在你可能还觉得node、zone、伙伴系统、slab这些东东还有那么一点点陌生。别怕,接下来我们结合动手观察,把它们逐个来展开细说。(下面的讨论都基于Linux 3.10.0版本)
在 Linux 中大页分为两种: Huge pages (标准大页) 和 Transparent Huge pages(透明大页)。
原文链接:https://rumenz.com/rumenbiji/linux-vmstat.html
原文链接:https://rumenz.com/rumenbiji/linux-vmstat.html 微信公众号:入门小站
在上一节, 我们介绍了Linux内核怎么管理系统中的物理内存. 但有时候内核需要分配一些物理内存地址也连续的内存页, 所以Linux使用了 伙伴系统分配算法 来管理系统中的物理内存页.
Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表。四级页表分别为:
随着计算需求规模的不断增大,应用程序对内存的需求也越来越大。为了实现虚拟内存管理机制,操作系统对内存实行分页管理。自内存“分页机制”提出之始,内存页面的默认大小便被设置为 4096 字节(4KB),虽然原则上内存页面大小是可配置的,但绝大多数的操作系统实现中仍然采用默认的 4KB 页面。 4KB 大小的页面在“分页机制”提出的时候是合理的,因为当时的内存大小不过几十兆字节,然而当物理内存容量增长到几 G 甚至几十 G 的时候,操作系统仍然以 4KB 大小为页面的基本单位,是否依然合理呢?
之前文章《Linux服务器性能评估与优化(一)》太长,阅读不方便,因此拆分成系列博文:
作者简介:许庆伟,Linux Kernel Security Researcher & Performance Developer 众所周知,Linux内核和CPU处理器负责将虚拟内存映射到物理内存。为了提高效率,在一个称为页的内存组中创建一个内存映射,其中每个页的大小根据处理器的实际情况而来。尽管大多数处理器也支持更大的页,但默认通常是4 KB,。内核可以从页空闲列表中为物理内存页的申请提供分配,并且为了提高效率,为每个DRAM组和CPU均设计了维护这些请求的方案。内核程序可以通过分配器(比如slab分配
常见的内存分配函数有malloc,mmap等,但大家有没有想过,这些函数在内核中是怎么实现的?换句话说,Linux内核的内存管理是怎么实现的?
最近一直在做性能压测相关的事情,有公众号的读者朋友咨询有赞的数据库服务器有没有开启huge page,我听说过huge page会对性能有所提升,本文就一探究竟。对过程没有兴趣的可以直接看结论。
本文主要分析 Linux 系统内存统计的一些指标以及进程角度内存使用监控的一些方法。
Linux 将物理内存分为内存段,叫做页面。交换是指内存页面被复制到预先设定好的硬盘空间(叫做交换空间)的过程,目的是释放对于页面的内存。物理内存和交换空间的总大小是可用的虚拟内存的总量。
Linux下的vmstat(英文全称:Virtual Meomory Statistics),虚拟内存统计的缩写,可对操作系统的虚拟内存、进程、CPU活动、I/O等系统整体运行状态进行监控。
案发现场的日志: 缓存集群redis重启错误报错: 29808:M 07 Jun 09:46:32.209 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 29808:M 07 Jun 09:46:32.209 # Server started, Redis version 3.0.4 2
.ss{ word-break: break-all; line-height:1; }
在用户的视角里,每个进程都有自己独立的地址空间,A进程的4GB和B进程4GB是完全独立不相关的,他们看到的都是操作系统虚拟出来的地址空间。但是呢,虚拟地址最终还是要落在实际内存的物理地址上进行操作的。操作系统就会通过页表的机制来实现进程的虚拟地址到物理地址的翻译工作。其中每一页的大小都是固定的。这一段我不想介绍的太过于详细,对这个概念不熟悉的同学回去翻一下操作系统的教材。
问题:我想要监测Linux系统的内存使用状况。有哪些可用的图形界面或者命令行工具来检查当前内存使用情况?
UNIX 是一个交互式系统,用于同时处理多进程和多用户同时在线。为什么要说 UNIX,那是因为 Linux 是由 UNIX 发展而来的,UNIX 是由程序员设计,它的主要服务对象也是程序员。Linux 继承了 UNIX 的设计目标。从智能手机到汽车,超级计算机和家用电器,从家用台式机到企业服务器,Linux 操作系统无处不在。
内存的管理和优化是系统性能优化的一个重要部分,内存资源的充足与否直接影响应用系统的使用性能。在进行内存优化之前,一定要熟悉Linux的内存管理机制,这里我们重点探讨如何通过系统命令监控Linux系统的内存使用状况。
内核和处理器负责将虚拟内存映射到物理内存。为了提高效率,会在称为页面的内存组中创建内存映射,其中每个页面的大小是处理器的详细信息。尽管大多数处理器也支持更大的容量,但通常有4 KB,Linux称其为 hugepage大页面。内核可以从其自己的空闲列表中为物理内存页面请求提供服务,内核为每个DRAM组和CPU维护这些请求以提高效率。内核自己的软件也通常通过内核分配器(例如slab分配器)从这些空闲列表中消耗内存。
理想情况下用户对内存的期待是大容量、高速度和持久性,但是现实中却是一个由缓存、主存、磁盘组成的内存架构,该架构中,缓存低容量、速度快但是成本高,主存中速度、中容量和中成本,磁盘就是大容量、持久性但是速度慢。
「 原谅和忘记就意味着扔掉了我们获得的最贵经验 -------《人生的智慧》叔本华」
我们知道linux系统内核的主要工作之一是管理系统中安装的物理内存,系统中内存是以page页为单位进行分配,每个page页的大小是4K,如果我们需要申请使用内存则内核的分配流程是这样的,首先内核会为元数据分配内存存储空间,然后才分配实际的物理内存页,再分配对应的虚拟地址空间和更新页表。
我们知道程序代码和数据必须驻留在内存中才能得以运行,然而系统内存数量很有限,往往不能容纳一个完整程序的所有代码和数据,更何况在多任务系统中,可能需要同时打开子处理程序,画图程序,浏览器等很多任务,想让内存驻留所有这些程序显然不太可能。因此首先能想到的就是将程序分割成小份,只让当前系统运行它所有需要的那部分留在内存,其它部分都留在硬盘。当系统处理完当前任务片段后,再从外存中调入下一个待运行的任务片段。的确,老式系统就是这样处理大任务的,而且这个工作是由程序员自行完成。但是随着程序语言越来越高级,程序员对系统体系的依赖程度降低了,很少有程序员能非常清楚的驾驭系统体系,因此放手让程序员负责将程序片段化和按需调入轻则降低效率,重则使得机器崩溃;再一个原因是随着程序越来越丰富,程序的行为几乎无法准确预测,程序员自己都很难判断下一步需要载入哪段程序。因此很难再靠预见性来静态分配固定大小的内存,然后再机械地轮换程序片进入内存执行。系统必须采取一种能按需分配而不需要程序员干预的新技术。
这些参数主要是用来调整virtual memory子系统的行为以及数据的写出(从RAM到ROM)。 这些节点(参数)的默认值和初始化的过程大部分都可以在mm/swap.c中找到。 目前,/proc/sys/vm目录下有下面这些节点:
过去,CPU的地址总线只有32位, 32的地址总线无论是从逻辑上还是从物理上都只能描述4G的地址空间(232=4Gbit),在物理上理论上最多拥有4G内存(除了IO地址空间,实际内存容量小于4G),逻辑空间也只能描述4G的线性地址空间。
本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制; 最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。
Huge pages ( 标准大页 ) 和 Transparent Huge pages( 透明大页 )
当涉及到Linux系统性能优化的时候,物理内存是一个最重要的因素。自然的,Linux提供了丰富的选择来监测珍贵的内存资源的使用情况。不同的工具,在监测粒度(例如:全系统范围,每个进程,每个用户),接口方式(例如:图形用户界面,命令行,ncurses)或者运行模式(交互模式,批量处理模式)上都不尽相同。
free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区。 参数讲解 bash-3.00$ free total used free shared buffers cached Mem: 1572988 1509260 63728 0 62800 277888 -/+ buffers/cache: 1168572 404416 Swap: 2096472 16628 2079844 Mem:表示物理内存统计 total:表示物理内存总量(total = used + free) used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。 free:未被分配的内存。 shared:共享内存,一般系统不会用到,这里也不讨论。 buffers:系统分配但未被使用的buffers 数量。 cached:系统分配但未被使用的cache 数量。 -/+ buffers/cache:表示物理内存的缓存统计 used2:也就是第一行中的used – buffers-cached 也是实际使用的内存总量。 //used2为第二行 free2= buffers1 + cached1 + free1 //free2为第二行、buffers1等为第一行 free2:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。 Swap:表示硬盘上交换分区的使用情况,这里我们不去关心。 系统的总物理内存:255268Kb(256M),但系统当前真正可用的内存b并不是第一行free 标记的 16936Kb,它仅代表未被分配的内存。 buffers与cached的区别 A buffer is something that has yet to be “written” to disk. A cache is something that has been “read” from the disk and stored for later use 对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。 所以从应用程序的角度来说 可用内存=系统free memory+buffers+cached. buffers是指用来给块设备做的缓冲大小,他只记录文件系统的metadata以及 tracking in-flight pages. cached是用来给文件做缓冲。 那就是说:buffers是用来存储,目录里面有什么内容,权限等等。 而cached直接用来记忆我们打开的文件,如果你想知道他是不是真的生效,你可以试一下,先后执行两次命令#man X ,你就可以明显的感觉到第二次的开打的速度快很多。 cached实验:在一台没有什么应用的机器上做会看得比较明显。记得实验只能做一次,如果想多做请换一个文件名。 #free #man X #free #man X #free 你可以先后比较一下free后显示buffers的大小。 buffers实验: #free #ls /dev #free 你比较一下两个的大小,当然这个buffers随时都在增加,但你有ls过的话,增加的速度会变得快,这个就是buffers/chached的区别。 因为Linux将你暂时不使用的内存作为文件和数据缓存,以提高系统性能,当你需要这些内存时,系统会自动释放(不像windows那样,即使你有很多空闲内存,他也要访问一下磁盘中的pagefiles) 简述swap 当可用内存少于额定值的时候,就会开始进行交换. 如何看额定值(RHEL4.0): #cat /proc/meminfo 交换将通过三个途径来减少系统中使用的物理页面的个数: 1.减少缓冲与页面cache的大小, 2.将系统V类型的内存页面交换出去, 3.换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。 事实上,少量地使用swap是不是影响到系统性能的。 使用free命令 将used的值减去 buffer和cache的值就是你当前真实内存使用 ————– 对操作系统来讲是Mem的参数.buffers/cached 都是属于被使用,所以它认为free只有16936. 对应用程序来讲是(-/+ buffers/cach).buffers/cached 是等同可用的,因为buffer/cached是为了
操作系统用于处理内存访问异常的入口操作系统的核心任务是对系统资源的管理,而重中之重的是对CPU和内存的管理。为了使进程摆脱系统内存的制约,用户进程运行在虚拟内存之上,每个用户进程都拥有完整的虚拟地址空间,互不干涉。而实现虚拟内存的关键就在于建立虚拟地址(Virtual Address,VA)与物理地址(Physical Address,PA)之间的关系,因为无论如何数据终究要存储到物理内存中才能被记录下来。
领取专属 10元无门槛券
手把手带您无忧上云