如何查看linux系统中空闲内存物理内存使用剩余内存

如何查看linux系统中空闲内存物理内存使用剩余内存,第1张

Linux将物理内存按固定大小的页面(一般为4K)划分内存,在内核初始化时,会建立一个全局struct

page结构数组mem_map[

]。如系统中有76G物理内存,则物理内存页面数为76*1024*1024k/4K=

19922944个页面,mem_map[

]数组大小19922944,即为数组中每个元素和物理内存页面一一对应,整个数组就代表着系统中的全部物理页面。

服务器中,存在NUMA架构(如Nehalem、Romly等),Linux将NUMA中内存访问速度一致(如按照内存通道划分)的部分称为一个节点(Node),用struct

pglist_data数据结构表示,通常使用时用它的typedef定义pg_data_t。系统中的每个结点都通过pgdat_list链表pg_data_t->node_next连接起来,该链接以NULL为结束标志。每个结点又进一步分为许多块,称为区域(zones)。区域表示内存中的一块范围。区域用struct

zone_struct数据结构表示,它的typedef定义为zone_t。更多详细的解答可以查看《Linux就该这么学》。

*** 作系统的内存管理,主要分为三个方面。

第一,物理内存的管理,相当于会议室管理员管理会议室。

第二,虚拟地址的管理,也即在项目组的视角,会议室的虚拟地址应该如何组织。

第三,虚拟地址和物理地址如何映射,也即会议室管理员如果管理映射表。

那么虚拟地址和物理地址如何映射呢?

每一个进程都有一个列表vm_area_struct,指向虚拟地址空间的不同的内存块,这个变量的名字叫mmap。

其实内存映射不仅仅是物理内存和虚拟内存之间的映射,还包括将文件中的内容映射到虚拟内存空间。这个时候,访问内存空间就能够访问到文件里面的数据。而仅有物理内存和虚拟内存的映射,是一种特殊情况。

如果我们要申请小块内存,就用brk。brk函数之前已经解析过了,这里就不多说了。如果申请一大块内存,就要用mmap。对于堆的申请来讲,mmap是映射内存空间到物理内存。

另外,如果一个进程想映射一个文件到自己的虚拟内存空间,也要通过mmap系统调用。这个时候mmap是映射内存空间到物理内存再到文件。可见mmap这个系统调用是核心,我们现在来看mmap这个系统调用。

用户态的内存映射机制包含以下几个部分。

物理内存根据NUMA架构分节点。每个节点里面再分区域。每个区域里面再分页。

物理页面通过伙伴系统进行分配。分配的物理页面要变成虚拟地址让上层可以访问,kswapd可以根据物理页面的使用情况对页面进行换入换出。

对于内存的分配需求,可能来自内核态,也可能来自用户态。

对于内核态,kmalloc在分配大内存的时候,以及vmalloc分配不连续物理页的时候,直接使用伙伴系统,分配后转换为虚拟地址,访问的时候需要通过内核页表进行映射。

对于kmem_cache以及kmalloc分配小内存,则使用slub分配器,将伙伴系统分配出来的大块内存切成一小块一小块进行分配。

kmem_cache和kmalloc的部分不会被换出,因为用这两个函数分配的内存多用于保持内核关键的数据结构。内核态中vmalloc分配的部分会被换出,因而当访问的时候,发现不在,就会调用do_page_fault。

对于用户态的内存分配,或者直接调用mmap系统调用分配,或者调用malloc。调用malloc的时候,如果分配小的内存,就用sys_brk系统调用;如果分配大的内存,还是用sys_mmap系统调用。正常情况下,用户态的内存都是可以换出的,因而一旦发现内存中不存在,就会调用do_page_fault。

浅谈服务器集群技术

为了使得多台系统能表现的如同一台服务器系统一样,那么就必须具备一个基本条件,就

是这么多台服务器系统,每台单独运行,都能提供完全一致的服务,否则,不同的服务器

提供不一致的服务,又如何对外表现出完全一致的表现呢?

这里,最简单的例子是Web服务器,我们可以设置Web服务器,使多个Web服务器中保存的网

页文件内容完全一致,这样,无论访问哪个服务器,只要使用同样的URL就能得到同样的结

果。

因此,在这个阶段要保证内容的一致性,就需要使用诸如服务器之间的同步镜像、网络存

储系统NAS或SAN,数据库的同步复制等等技术。

2. 实现:任务调度

当所有的服务器都具备一致性的表现,接下来的任务就是将任务按照一定的方式分配给这

些服务器,这就是任务调度。

实现任务调度首先需要要将任务尽可能的按照小粒度分割,每个粒度应该是能够在不同服

务器部分上单独执行的最小单位。粒度划分的越小,任务分割得越平均,因而整体效果就

越好。但粒度的划分是有一定条件的,粒度越小,粒度之间的关联就越紧密,例如在SMP多

处理器的计算机系统中,任意一个线程都可以在任一个处理器上执行,因此执行粒度可以

划分为线程,但是线程之间是共享内存的,这已经在理论上提出,并在并行计算机上实现

,但在不同服务器之间目前还是不现实的。

由于大多数网络服务都是基于TCP网络连接的,因此最简单的考虑,可以按照TCP连接划分

任务粒度,这适合包括Web服务,数据库连接等绝大多数情况。

实现任务调度的方式有很多种,一种方法是在系统内部完成,所有的服务器能够自我协调

,完成任务调度,这种方法要涉及所有的服务器,依赖于具体的应用系统,因而更为复杂

。另一种方法是不在服务器之间实现调度,而依赖于外部的任务调度设备执行调度。

无论那种任务调度方式,最大的问题就是害怕任务调度本身带来的额外消耗或性能瓶颈,

因此使用硬件设备和单一的高效率系统,作为外部任务调度设备,成为了集群的首选方案

3. 外部任务调度:负载平衡和虚拟服务器

使用外部任务调度设备对任务按照网络连接进行分配,这种情况通常被称为网络服务器的

负载平衡。外部的任务调度设备有很多种,例如基于BSD/OS的F5,CISCO的LocalDirector

,以及一些七层交换机,例如Foundry的交换机等等,我也曾在98年基于FreeBSD的NATD做

过这方面的探讨。目前,除了一些基于硬件交换机设备之外,完全软件的实现中最为流行

的就是LVS,Linux Virtual Server,作为一个开放源代码的项目,他得到了Linux社区的

大力支持,并用于大部分Linux集群设备中。

LVS是由国防科技大学的章文松提出的一个开放源代码项目,事实上这也是国内Linux开发

工作中最被国际认可的一个工作,这也标志着国内在这个方向上的研究并不次于国际同行

LVS中最为优秀的特点是实现了策略路由的观念,它允许一个TCP连接由任务分配设备分配

给后端服务器中之后,后端服务器使用不同的路由,不再经过任务分配器,而是直接返回

给客户,这种方式需要后端服务器也是Linux设备,因此不是简单的任务调度。

4. 服务器负担:容错与监控

任务调度的关键是将所有的任务平均的分配给所有的服务器,如果不能做到合理的分配,

就能出现部分服务器上的拥塞现象,此时还可能有后台服务器类型差异造成的处理能力的

不一致等情况。

为了达到这个任务分配的目的,必须使用一种方法来获得服务器状态,这里就有不同的几

种方法。最简单的方法是按照当前服务器的任务数量来衡量服务器负荷,通常就是按照网

络连接的数量来衡量,这种方法应该是比较模糊的,因此不同的连接对服务器造成的压力

是不同的,例如一个静态网页的处理和一个后台CGI程序的处理,服务器负担就绝对不同。

一些负载均衡设备通过测量设备对网络连接响应时间来判断服务器的负荷,这基本上能够

反映一些情况,但也并非绝对如此,因为优秀的服务器对于基本的网络响应是迅速的,但

对于后面的处理过程则受系统负荷的影响。

因此,一些系统甚至引入了客户/服务器机制,在后台服务器中安装代理来完成探测系统

性能的任务。

当任务调度设备能够精确的了解服务器负荷的时候,它显然就能够达到了解后台服务器的

可用性,就是说任务调度设备能够检测出某些后台服务器不能正确运行,从而避开这个服

务器,将任务分配给其他设备,达到容错的目的。

5. 共享数据:会话管理

还是以Web访问为例,对于普通的网页,不同的HTTP连接就可以认为是不同的任务。但是,

对于更复杂的应用,例如需要用户登录,并根据不同用户提供不同服务的情况呢?

此时,如果仍然还是要把不同的HTTP连接看作不同的任务,那么这些连接之间实际上还是

有一定关系的,事实上每个用户从登录到退出,可以被看作一个完整的HTTP会话。

由于这些会话必须保存的数据比较少,例如仅仅是用户名和简单的一些秘密设置,任务调

度的时候可以不考虑这些会话,那么就可能发生这样的情况,同一个会话的不同HTTP连接

可能在不同的后台服务器上进行处理,因此这就需要进行这些服务器之间的数据共享。数

据共享可以通过多种方式,通过共享的存储空间,通过独立的服务程序,通过数据库,甚

至通过共享网络间内存等等。

虽然任务调度程序可以不理会这种会话,不同服务器之间可以共享,但如果能够支持会话

功能,使得同一个会话可以被同一个服务器所处理,这样会带来效率上的提高。因此,一

些任务调度设备提出了“粘滞”的概念,能够根据Cookie或其他标记判断会话,并导向同

一个服务器。

6. 相关技术

虽然目前用于解决网络服务的集群技术,在技术层次上比较简单,事实上只是应用了此前

并行计算技术研究的一些简单方面,但在实用化方面的作用还是很明显的。

但在理论上,目前所使用网络服务器集群技术还是有很大的挖掘之处,例如,目前的任务

调度的粒度是基于TCP连接的,如何更细化。目前,在并行计算领域,人们使用PVM和MPI,

允许运行在不同计算机上的多个进程进行协同,在进程之内可以进行任务调度,粒度被切

割到更细致的计算单元,如果能将这些概念应用于集群系统,必然能更好的解决对大负载

任务的处理任务,缩减处理时间。

此外,目前一旦任务调度设备将任务分配给一个服务器,那么这个任务就一定在这个服务

器上运行,直到完成。有时,人们需要将一个任务从一个服务器透明的迁移到另一个服务

器正常执行,目前,在Linux上的Mosix能达到这个目标。

事实上,PVM、MPI、Mosix等等技术,都是构建用于计算目的的Linux集群计算机的有效工

具。用于处理计算的Linux集群计算机是由多台Linux节点构成的超级计算机,主要用来处

理计算任务,他们处理的任务通常要比用于网络服务的集群计算机更为复杂,使得节点之

间的I/O非常频繁,造成了相当多的额外负荷(例如一个进程从一个节点迁移到另一个节点

上的网络负荷)。

因此,对于处理网络服务来讲,由于服务类型简单,目前的这种集群方式还是比较实用的

做游戏集群还真的不知道!!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7322054.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-04
下一篇 2023-04-04

发表评论

登录后才能评论

评论列表(0条)

保存