文章
服务器与存储管理
2014 年 4 月发布
第 1 部分 — 使用 COMSTAR 和 ZFS 配置虚拟化存储环境
第 2 部分 — 使用交换监视和使用 ZFS 卷扩大交换空间
第 3 部分 — 使用 ZFS 影子迁移
第 4 部分 — 将 ZFS 数据集委托给非全局区域
第 5 部分 — 使用 ZFS 加密
第 6 部分 — 使用 ZFS 快照
安装过程中,Oracle Solaris 11 通常将交换空间设置为约四分之一 RAM 大小。每种环境的系统(特别是应用)要求各不相同,因此通常需要添加或删除空间来修改交换空间大小。
|
交换空间是磁盘上的一个专用区域,用于存储因 RAM 空间不够而移出的分页匿名内存和进程。
查看系统上当前空间交换大小的办法有多种,例如:
root@solaris11-1:~# swap -l swapfile dev swaplo blocks free /dev/zvol/dsk/rpool/swap 285,2 8 2097144 2097144
其中:
swapfile 指示来自 /dev/zvol/dsk/rpool/swap 中的 ZFS 卷的交换空间。dev 显示主设备号,本例中确认了交换对象确系基于 ZFS 卷:root@solaris11-1:~# more /etc/name_to_major | grep 285 zfs 285
swaplo 指示可能的最低交换空间大小,它代表内存页大小(8 扇区 x 512 字节 = 4K)。要查看此大小,可执行以下命令获得 pagesize:root@solaris11-1:~# pagesize 4096
Intel 计算机上此值通常为 4K。但对于 SPARC 计算机上的 Oracle Solaris 11,页面大小可能在 16K 至 2 GB 之间(此上限也适用于 Intel 处理器)。此上限主要用作系统全局区域 (SGA) 的页面大小,SGA 是 Oracle Database 11g 实例的专用共享内存区域。此外,值得注意的是,Oracle Solaris 10 8/11 或更高的 Oracle Solaris 版本和 Oracle SPARC T4 处理器支持 2 GB 页面,但默认情况下不启用此页面大小。如果此页面大小适合某些应用,我们必须在 /etc/system 文件中插入 set max_uheap_lpsize=0x80000000,然后重新启动系统来启用它。
而且,Oracle Solaris 11 支持多种页面大小,可根据应用配置文件手动设置,或者通过新的内置内存预测技术(它能够分析应用需求,分配一个合适的值)自动设置。
运行以下命令(本例中是在 Intel 处理器上)可显示受支持的页面大小:
root@solaris11-1:~# pagesize -a 4096 2097152
以上示例显示支持两种页面大小:4K 和 2 GB。使用更大的内存页面的真实原因是通过减少 TLB(转换后备缓冲区)未命中次数提高内存管理单元 (MMU) 性能。可以使用 trapstat 命令(虽然 trapstat 通常不会在 Intel 平台上实现)验证 TLB 未命中次数。
blocks 是交换空间的总大小(2097144 x 512 字节 = 1 GB)。free 代表空闲交换空间 (1 GB)。以下命令是监视交换空间的另一个好办法:
root@solaris11-1:~# swap -s total: 680180k bytes allocated + 266516k reserved = 946696k used, 2321756k available
从命令输出可以看到以下内容:
680180K bytes allocated 表示已经使用(即以前分配过但此时并不一定仍在使用)以及继续可用和保留的交换空间量。大致相当于上限阈值。266516k reserved 表示尚未分配但已声明供将来可能的使用的交换空间。记住,在为进程创建虚拟内存(堆段或匿名内存)时保留交换空间,然后在进程运行时分配保留的交换空间。组成匿名内存 的页面要么在任何文件系统中均无对应物,要么因物理内存 (RAM) 不足 — 可能是因为堆栈、共享内存和进程堆(例如来自 malloc 函数)大于可用内存量 — 而迁移到交换空间。946696k used 表示分配或保留的交换空间总量。2321756k available 表示可用于将来分配的交换空间。此外,我们还必须记住,在为进程创建虚拟内存时保留了一些交换空间,但此保留空间只有一部分真正与该进程的地址空间关联;否则,可能会错误地解释 swap -s 输出,因为它指示最终保留了(为了分配空间,必须先保留空间)946696k,而已分配的交换空间是 680180K。
另一个要点是 swap -l 命令报告(磁盘上的)物理交换空间,而 swap -s 报告虚拟交换空间,是物理交换空间和物理内存之和。因此,swap -s 报告的可用交换空间是空闲 物理交换空间加空闲 物理内存空间之和。因此,不建议使用 swap -s 命令估算物理交换空间;而应使用 swap -l。
如果我们要尝试其他办法获取交换信息,可以使用 echo ::swapinfo | mdb -k 命令,例如:
root@solaris11-1:~# echo ::swapinfo | mdb -k
ADDR VNODE PAGES FREE NAME
ffffc10007798260 ffffc10007a7db40 262143 262143 /dev/zvol/dsk/rpool/swap
确认 262143 页 x 8K = 2097144K 很简单。
如前所述,最好记住匿名内存在文件系统中没有对应物。通常,匿名页面是进程的私有数据,包括进程堆(匿名数据)和线程结构(如堆栈区域)。
交换 — 交换程序进程 (sched) 的一个操作,换出睡眠超过 20 秒的进程(先是线程结构,然后是堆栈和堆数据 [匿名页面]) — 不应与分页 混淆,分页将页面(通常每页 4 KB 或 8 KB)从内存移到磁盘,通常可实现极高的内存管理效率。但是,有一种分页会严重影响系统性能 — 匿名分页(主要是匿名页面调入),因为它会增加从磁盘读回数据的应用延迟。
而且,不应将交换与回收 (reaping) 混淆,后者是从内核 slab 分配器缓存释放内存的技术,由函数 kmem_reap( ) 执行。
如何验证系统是否使用匿名页?在以下输出中,主要关注 apo(匿名页面调出)和 api(匿名页面调入)列,理想情况下,这两列均应等于 0。后者导致应用延迟增加。
root@solaris11-1:~# vmstat -p 1
memory page executable anonymous filesystem
swap free re mf fr de sr epi epo epf api apo apf fpi fpo fpf
2973844 2609240 3 18 0 0 3 0 0 0 0 0 0 0 0 0
2895156 2544236 26 47 0 0 0 0 0 0 0 0 0 0 0 0
2895156 2544092 0 0 0 0 0 0 0 0 0 0 0 0 0 0
要查明哪个进程在执行匿名页面调入,请使用以下命令:
root@solaris11-1:~# dtrace -n 'vminfo:::anonpgin { @[pid, execname] = count(); }'
大量页面扫描(搜索空闲内存页)表明分页释放的内存不足以应用需求,此时,交换是最后的手段。
通常,当空闲内存量低于 desfree 内核参数指定的数量和 minfree 内核参数指定的数量时,页面扫描会变得更加频繁。如果空闲内存量持续低于 desfree 值至少 30 秒,系统将启动交换。
最糟糕的交换形式是硬交换,即卸载某些不活动的内核模块并将其移到交换空间。
可以使用以下命令监视系统是否在进行硬交换:
root@solaris11-1:~# echo "hardswap/D" | mdb -k hardswap: hardswap: 0
硬交换极少发生,因为它必须满足以下条件:
desfree 至少 30 秒,且vmstat 输出中的 r 列)中必须始终有两个待处理的进程,且freemem 必须低于 minfree,或者页面调入数加页面调出数必须大于 maxpgio,其中 maxpgio 是分页系统能够排入队列中的页面调出请求数。换句话说,maxpgio 用于限制在不导致磁盘 I/O 瓶颈的情况下可以发送到交换的内存页数。因此,maxpgio 基于使用自己的磁盘控制器的交换设备数。其默认值为 40 页。
更常见的是一种名为软交换 的轻型交换,发生在空闲内存量低于 desfree 值时。
执行以下命令可以检查软交换:
root@solaris11-1:~# echo "softswap/D" | mdb -k softswap: softswap: 0
简单介绍一下(更多详情不在本文范围内),minfree 值等于 desfree/2,desfree 值等于 lotsfree/2。以下是计算 lotsfree 的公式:
lotsfree = [memory - kernel]/(64 * page size)]
运行以下命令可以看到这些值:
root@solaris11-1:~# prtconf | grep -i memory
Memory size: 4096 Megabytes
root@solaris11-1:~# echo lotsfree/D | mdb -k
lotsfree:
lotsfree: 16318
root@solaris11-1:~# echo desfree/E | mdb -k
desfree:
desfree: 8159
root@solaris11-1:~# echo minfree/D | mdb -k
minfree:
minfree: 4079
root@solaris11-1:~# bc
16318 * 4096 * 64
4277665792
root@solaris11-1:~#
获取 lotsfree、desfree 和 minfree 值的最好办法是执行以下命令:
root@solaris11-1:~# kstat -n system_pages
module: unix instance: 0
name: system_pages class: pages
availrmem 409132
crtime 0
desfree 8159
desscan 25
econtig 4229439488
fastscan 522183
freemem 243665
kernelbase 0
lotsfree 16318
minfree 4079
nalloc 110633425
nalloc_calls 31285
nfree 107403292
nfree_calls 23611
nscan 0
pagesfree 243665
pageslocked 635234
pagestotal 1044366
physmem 1044366
pp_kernel 649290
slowscan 100
snaptime 26017.87927546
回到页面扫描的话题,对于在不同时间发生的页面扫描,有不同的值。例如,fastscan 是空闲内存等于 0 时每秒扫描的页面数,desscan 是页面扫描期间的扫描速度目标,nscan 是上次页面扫描操作期间扫描的页面数。在本例中,内存充足,没有任何页面扫描活动(nscan 等于 0)。
运行以下命令可从 kstat 收集到相同的信息:
root@solaris11-1:~# echo fastscan/E | mdb -k fastscan: fastscan: 522183 root@solaris11-1:~# echo slowscan/E | mdb -k slowscan: slowscan: 100 root@solaris11-1:~# echo desscan/E | mdb -k desscan: desscan: 25 root@solaris11-1:~# echo nscan/E | mdb -k nscan: nscan: 0
要监视交换空间,可以执行以下命令检查过去和当前(实时)的交换统计信息:
root@solaris11-1:~# vmstat 1 kthr memory page disk faults cpu r b w swap free re mf pi po fr de sr s0 s2 s3 s4 in sy cs us sy id 0 0 0 2972960 2608516 3 18 0 0 0 0 3 0 0 0 0 659 480 723 1 4 95 0 0 0 2895104 2544208 26 49 0 0 0 0 0 0 0 0 0 660 648 694 1 4 95 0 0 0 2895104 2544056 0 2 0 0 0 0 0 0 0 0 0 690 1839 847 4 4 92
对我们而言,重要的是 w 列,当空闲内存量降至低于 minfree 或 desfree 超过 30 秒时,需要将空闲进程换出到交换空间,该列显示由此可能产生的内存压力导致换出的线程。
以下命令显示实时交换状态:
root@solaris11-1:~# vmstat -S 1 kthr memory page disk faults cpu r b w swap free si so pi po fr de sr s0 s2 s3 s4 in sy cs us sy id 0 0 0 2972572 2608200 0 0 0 0 0 0 3 0 0 0 0 659 480 723 1 4 95 0 0 0 2895032 2544000 0 0 0 0 0 0 0 0 0 0 0 706 875 901 2 5 93 0 0 0 2895032 2544000 0 0 0 0 0 0 0 0 0 0 0 615 511 671 1 3 96
so 和 si 列分别表示实时换出页和换入页。同样,理想情况下,为取得良好性能,二者均应为 0。
我们已经知道如何监视交换空间,下面来了解如何添加和删除分配给交换区域的磁盘空间。我们使用的 Oracle Solaris 11 主机 (solaris11-1) 具有以下文件系统相关的组件:
root@solaris11-1:~# zfs list -r rpool NAME USED AVAIL REFER MOUNTPOINT rpool 28.5G 49.7G 4.91M /rpool rpool/ROOT 25.4G 49.7G 31K legacy rpool/ROOT/solaris 25.4G 49.7G 24.4G / rpool/ROOT/solaris-backup-1 138K 49.7G 24.2G / rpool/ROOT/solaris-backup-1/var 64K 49.7G 291M /var rpool/ROOT/solaris/var 486M 49.7G 234M /var rpool/VARSHARE 92K 49.7G 92K /var/share rpool/dump 2.06G 49.8G 2.00G - rpool/export 805K 49.7G 32K /export rpool/export/home 773K 49.7G 32K /export/home rpool/export/home/ale 741K 49.7G 741K /export/home/ale rpool/swap 1.03G 49.7G 1.00G -
最后一行指示交换空间为 1GB,是一个 ZFS 卷。可通过执行以下命令验证此信息:
root@solaris11-1:~# ls -l /dev/zvol/rdsk/rpool/swap lrwxrwxrwx 1 root root 0 Dec 2 06:31 /dev/zvol/rdsk/rpool/swap -> ../../../..//devices/pseudo/zfs@0:2,raw
因此,更改其大小是可行的,因为 rpool 有些空闲空间,而交换卷属于 rpool 存储池:
root@solaris11-1:~# zfs get volsize rpool/swap NAME PROPERTY VALUE SOURCE rpool/swap volsize 1G local root@solaris11-1:~# zfs set volsize=2G rpool/swap root@solaris11-1:~# zfs get volsize rpool/swap NAME PROPERTY VALUE SOURCE rpool/swap volsize 2G local root@solaris11-1:~# swap -l swapfile dev swaplo blocks free /dev/zvol/dsk/rpool/swap 285,2 8 097144 2097144 /dev/zvol/dsk/rpool/swap 285,2 097160 097144 2097144 root@solaris11-1:~# swap -s total: 451556k bytes allocated + 259888k reserved = 711444k used, 3886000k available root@solaris11-1:~# zfs list -r rpool/swap NAME USED AVAIL REFER MOUNTPOINT rpool/swap 2.06G 48.7G 2.00G - root@solaris11-1:~#
不过,并不总是可以更改交换空间的属性,因为它可能很忙。因此,有时需要将另一个卷添加到 rpool 存储池,之后在 /etc/vfstab 末尾插入一行,自动挂载该卷:
root@solaris11-1:~# zfs create -V 2G rpool/newswap root@solaris11-1:~# swap -a /dev/zvol/dsk/rpool/newswap root@solaris11-1:~# swap -l swapfile dev swaplo blocks free /dev/zvol/dsk/rpool/swap 285,2 8 2097144 2097144 /dev/zvol/dsk/rpool/swap 285,2 2097160 2097144 2097144 /dev/zvol/dsk/rpool/newswap 285,4 8 4194296 4194296 root@solaris11-1:~# swap -s total: 453668k bytes allocated + 260304k reserved = 713972k used, 5962264k available root@solaris11-1:~# zfs list -r rpool NAME USED AVAIL REFER MOUNTPOINT rpool 31.6G 46.6G 4.91M /rpool rpool/ROOT 25.4G 46.6G 31K legacy rpool/ROOT/solaris 25.4G 46.6G 24.4G / rpool/ROOT/solaris-backup-1 138K 46.6G 24.2G / rpool/ROOT/solaris-backup-1/var 64K 46.6G 291M /var rpool/ROOT/solaris/var 486M 46.6G 234M /var rpool/VARSHARE 92K 46.6G 92K /var/share rpool/dump 2.06G 46.7G 2.00G - rpool/export 805K 46.6G 32K /export rpool/export/home 773K 46.6G 32K /export/home rpool/export/home/ale 741K 46.6G 741K /export/home/ale rpool/newswap 2.06G 46.7G 2.00G - rpool/swap 2.06G 46.7G 2.00G - root@solaris11-1:~# more /etc/vfstab #device device mount FS fsck mount mount #to mount to fsck point type pass at boot options # /devices - /devices devf - no - /proc - /proc proc - no - Ctfs - /system/contract ctfs - no - Objfs - /system/object objfs - no - Sharefs - /etc/dfs/sharetab sharefs - no - Fd - /dev/fd fd - no - Swap - /tmp tmpfs - yes - /dev/zvol/dsk/rpool/swap - - swap - no - /dev/zvol/dsk/rpool/newswap - - swap - no -
显然,反过来就是删除交换空间的过程。例如,执行以下命令,然后删除 /etc/vfstab 文件中的最后一行:
root@solaris11-1:~# swap -d /dev/zvol/dsk/rpool/newswap
以下是我撰写的其他一些文章的链接:
以下是有关 Oracle Solaris 11 的一些资源:
Alexandre Borges 是一位 Oracle ACE,曾于 2001 至 2010 年任职于 Sun Microsystems,并担任签约讲师,主要负责讲授 Oracle Solaris、Oracle Solaris Cluster、Oracle Solaris 安全性、Java EE、Sun 硬件和 MySQL 课程。目前,他为 Symantec、Oracle 合作伙伴、Hitachi 和 EC-Council 提供课程教学,并且讲授一些关于信息安全的非常专业的课程。此外,他还是 Linux Magazine Brazil 的特约撰稿人和专栏作家。
| 修订版 1.0,2014 年 4 月 9 日 |