本文假设用户的主要文件系统驻留在硬盘之上。硬盘是系统中相对于 CPU、内存等设备来说活动时间比较少的部件。如果硬盘处于空闲状态时,耗电量是很少的;而在启动进行读写的时候,耗电量会大大增加。所以通过文件系统节能的核心思想就是,尽量减少磁盘 I/O,使硬盘更多的处于空闲状态。
对 atime 的处理
根据 POSIX 的规定,Linux 以及 Unix 等系统都要为系统中的所有文件记录文件的最后访问时间,叫做 atime。对于某些应用来说,atime 是很重要的信息。比如一些邮件程序会通过邮件文件的 atime 来判断此邮件是否已读;一些备份和清理程序会根据文件在多长时间内没有被访问,来决定是否对文件进行清理和归档。
但是对于大部分应用来说,atime 信息并不重要,而系统更新 atime 所带来的开销却是巨大的。因为系统每访问一次某个文件,就要对这个文件更新一个新的 atime 时间值。我这里所说的访问,并不是从用户角度来看的打开一个文件,而是系统底层的每一次 open 和 read 等操作。设想一下,我们每对文件进行一次读操作,都要引起一个对磁盘的写操作,即使我们要读的内容已经存在于内存的 Page Cache 中,还是要对磁盘进行一个写操作。这样引起的开销确实是巨大的,这些写操作会使磁盘更多的处于忙碌状态,这对系统性能(因为磁盘在完成一个写操作的时候会暂时阻止其他的写操作)以及电量消耗都是不利的。
所以,如果用户可以确定自己的应用不会使用到文件的 atime 信息,则可以禁止 atime 的更新。对于整个文件系统,mount 命令的 noatime 选项可以使整个文件系统下的文件都不会进行 atime 的更新。可以使用如下命令:
mount -o remount,noatime /
也可以将 noatime 选项写在 /etc/fstab 文件里。
如果不想对整个文件系统禁止 atime 更新,而只是想针对某些文件或目录禁止,则可以通过 chattr 命令来完成,如下面的命令:
chattr -R +A /some/dir
可以对某个目录及其下面的所有文件禁止 atime 更新。
除了 noatime,还有两个和 atime 相关的文件系统选项。一个是 nodiratime,此选项只针对目录禁止进行 atime 更新(注意 noatime 对文件和目录都生效,是 nodiratime 的超集)。这样就可以使 ls这样的命令不会更新目录的 atime 值。
对于某些用户某些应用,atime 信息可能是必要的,比如本节一开始提到的邮件程序和备份工具。如果完全禁止 atime 更新会使这些程序无法正常工作。针对这种情况,Linux 在内核 2.6.20 中添加了一个新的 mount 选项 relatime(relative atime 的意思)。relatime 的意思是访问文件时,仅在 atime 早于文件的更改时间时对 atime 进行更新。在内核 2.6.24 中,又对 relatime 进行了扩展,在访问文件时,当 atime 已经超过某个时间(例如一天)没有更新,就对 atime 进行更新。这个扩展的意思就是调整 atime 的更新粒度。
目前 relatime 还没有被广泛的应用,因为许多 Linux 发行版的内核版本和 mount 命令还没有支持这个选项。如果你的系统支持 relatime,可以使用如下命令启用:
mount -o remount,relatime /
回页首
调节 Page Cache 和 VM 系统
调节 Page Cache
在 Linux 的内核中,对文件的读写提供一个页面缓冲的机制(Page Cache)。Page Cache 存在于内存中,当要读取一个磁盘文件的内容时,内核首先在 Page Cache 中进行查找,如果要读取的内容已经存在 Page Cache 中,则无需在对磁盘发起实际的读操作。同样在需要写文件时,写操作也只是将内容存放于 Page Cache 中,而 Page Cache 中的更改内容由内核进程 pdflush 周期性的写回磁盘。在默认情况下,pdflush 进程每 5 秒钟醒来一次,进行数据写回操作。这个写回时间值定义在参数 /proc/sys/vm/dirty_writeback_centisecs中。如果在这 5 秒钟之间,发生电源故障或者系统崩溃,可能会引起数据丢失。如果用户的电源供应比较可靠,或者丢数据丢失的风险不是非常在意,可以适当的提高这个数据写回时间。使用如下命令查看系统当前的写回时间值:
cat /proc/sys/vm/dirty_writeback_centisecs 500
此时间值的单位为 1/100 秒。使用如下命令可以更改此值:
echo 2000 > /proc/sys/vm/dirty_writeback_centisecs
这样,就可以使 pdflush 进程 20 秒才醒来一次,从而减少对磁盘的访问频率。
还有一个参数 /proc/sys/vm/dirty_expire_centisecs控制一个更改过的页面经过多长时间后被认为是过期的、必须被写回的页面,其默认值是 3000(单位也是 1/100 秒)。用户也可以适当的增加此值,使页面更长时间的驻留在内存中。如下命令:
echo 4000 > /proc/sys/vm/dirty_expire_centisecs
pdflush 进程处理的另一种情况是当可用内存量降低的时候,会将一些缓冲页面写回磁盘,释放内存。这个行为是受 /proc/sys/vm/dirty_background_ratio参数控制的,此参数的默认值为 10,意思是当所有被更改页面总大小占工作内存超过 10% 时,pdflush 会开始写回工作。用户可以增加这个比例,以增加页面驻留在内存的时间。此参数的更改方法同上面两个参数。
Swap 分区或文件
在默认情况下,Linux 内核并不是只有在物理内存不够用的时候才进行交换,而是为了保证尽量大的磁盘缓冲以及其他一些原因,会尽可能的将非活动的进程及内存页面交换出内存,放在磁盘上的交换分区中。这种默认行为使得在还有大量内存可用的情况下,就会发生交换操作,而释放出的物理内存并没有被利用起来,显然这些交换操作是不必要的。为了减少因交换引起的磁盘读写,在用户内存足够大的时候,可以考虑禁用 swap 分区。
回页首
使用“笔记本模式”(laptop mode)
在 2.6.6 以后,Linux 内核在 I/O 系统上支持一种“笔记本模式”。在“笔记本模式”下,内核更智能的使用 I/O 系统,它会尽量使磁盘处于低能耗的状态下。“笔记本模式”会将许多的 I/O 操作组织在一起,一次完成,而在每次的磁盘 I/O 之间是默认长达 10 分钟的非活动期,这样会大大减少磁盘启动的次数。为了完成这么长时间的非活动期,内核就要在一次活动期时完成尽可能多的 I/O 任务。在一次活动期间,要完成大量的预读,然后将所有的缓冲同步。在非活动期间,写操作会被阻挡在内存中(读操作如果无法在 Cache 中满足,则无法阻挡,因为用户无法忍受这么长时间的延迟)。“笔记本模式”会根据需要设置上节介绍的参数来达到适当的目的。
使用如下命令查看“笔记本模式”是否启用:
cat /proc/sys/vm/laptop_mode 0
0 表示没有启用,可以使用如下命令启用:
echo 5 > /proc/sys/vm/laptop_mode
回页首
配置 syslog
Linux 使用 syslog 记录内核和各种应用程序的日志信息。Linux 系统里存在一个 Daemon 进程 syslogd 或 sysklogd 来完成 syslog 的功能。默认设置下,syslogd 在每次记录一条日志后,都会使用同步(sync)操作强制将页面缓存同步到磁盘上。这样做是为了保证日志信息得到最大的保护,即使系统崩溃或电源故障,日志信息可以最大可能的被写到了磁盘上。
但是在个人电脑等对日志信息要求不是如此严格的系统上,这些 sync 操作很耗费磁盘 I/O,同时耗费更多的电量。如果想禁止 syslog 的这种 sync 行为,需要修改 syslog 配置文件 /etc/syslog.conf,在不想进行 sync 操作的项目前添加一个“-”(减号)。
如将下面这一行:
*.info;mail.none;authpriv.none;cron.none /var/log/messages
改为:
*.info;mail.none;authpriv.none;cron.none -/var/log/messages
对于不是特别重要的日志信息,都可以采用以上方法禁止 sync 行为。
用户也可以根据自己的需要,将 /etc/syslog.conf 里不必要的日志项去掉,甚至可以将 syslogd 停掉,以节省磁盘 I/O。
回页首
使用 tmpfs
tmpfs(temporary file system)是一种基于内存的文件系统,类似于虚拟磁盘 ramdisk,但还是有很大不同。传统的 ramdisk 是一个块设备,而 tmpfs 是一个文件系统,并不是块设备,只是安装它,就可以使用。tmpfs 一开始使用很小的空间,但随着文件的复制和创建,tmpfs 文件系统会分配更多的内存,并按照需求动态地增加文件系统的空间。而且,当 tmpfs 中的文件被删除时,tmpfs 文件系统会动态地减小文件系统并释放内存资源。但是 tmpfs 中的内容会在文件系统卸载后丢失。
用户可以将 tmpfs 应用于 /tmp 目录,这样在系统运行时产生的临时文件,以及对这些临时文件的读写都只发生在内存里,而不会引起任何的磁盘 I/O。
如要使用最大为 100M 的 tmpfs 在 /tmp 目录上,可以将以下这行添加到 /etc/fstab 中:
tmpfs /tmp tmpfs size=100m,mode=1777 0 0
阅读(804) | 评论(0) | 转发(0) |