好像一年多没写东西了诶…… 其实寒假就想写点啥,但都因为拖延症没写成。可见维护博客也是个挺麻烦的事。这次为了避免拖延,写点简单的东西好了。
Archwiki 的 Maximizing performance 一文很早就提到 “Compressing /usr” 这么个优化方式。就是用 squashfs 压缩 /usr(squashfs 是只读的),然后上面加一层 aufs 实现读写支持。好处就是减小磁盘空间占用,从而减轻 I/O 负担,
不过后来 Linux 内核把 aufs 踢出去了,这个优化也就坑了。加上现在 Arch 现在基本把所有东西都放进了 /usr,init 进程对 /usr 依赖特别强,分出去可能会有各种毛病。于是就不再建议搞这个优化了。
前阵子搞学校图书馆的网络启动查询机。实现是:Arch 系统,文件放在 NFS 上的 squashfs 里,用 aufs 读写。于是重新折腾起 aufs + squashfs 了。后来索性在自己机器上也搞了个,不是压 /usr,而是压 /usr/share。这里就记录一下配置吧。
先说说目录结构。文件系统相关文件都放在 /sfs/usr_share/:
/sfs/usr_share/filesystem.sfs
/sfs/usr_share/ro
/sfs/usr_share/rw
下面的操作其实都可以开着系统在线完成的,除了最后删除 /usr/share 的部分。
一条命令的事儿:
mksquashfs /usr/share /sfs/usr_share/filesystem.sfs \
-b 32k -comp lzo -Xcompression-level 9
稍微解释:
按道理说,应该在 fstab 里加上相关项就可以了。但实际上我遇到了很严重的问题,开机经常没挂上 /usr/share。我没仔细追原因,感觉好像是因为 systemd 对挂载顺序作出了些调整,导致了一些问题。最后试了试 systemd 引入的新东西,解决了问题。
众所周知,systemd 造了好多轮子,什么 crontab、网络管理器、日志服务 它都想给接替了。fstab 也是这样,systemd 引入了 .mount 单元这么个东西,用于控制文件系统挂载。
虽然 Arch 还没抛弃 fstab,但其实 fstab 中有些内容已经被 systemd 完全取代了。老 Arch 用户可能记得,以前 /dev、/tmp 的挂载都是要写进 fstab 的,但现在都不用写了。Arch 用户可以看看 systemd 包提供的 /usr/lib/systemd/system/tmp.mount
这个文件,就是 /tmp 的挂载配置。内容很好理解,就不贴了。
正如 systemd 引入的各种单元(unit)一样,mount 单元也可以写各种依赖啊什么的东西,从这点来讲它比 fstab 的功能要强大。这里挂载 /usr/share 就要用到依赖关系:可读分支要在 /usr/share 挂载之前完成挂载。
直接贴文件:
[Unit] Description = /usr/share, read-only branch [Mount] What = /sfs/usr_share/filesystem.sfs Where = /sfs/usr_share/ro Type = squashfs Options = defaults [Install] WantedBy = local-fs.target
[Unit] Description = /usr/share Requires = sfs-usr_share-ro.mount After = sfs-usr_share-ro.mount [Mount] What = none Where = /usr/share Type = aufs Options = br:/sfs/usr_share/rw=rw:/sfs/usr_share/ro=ro [Install] WantedBy = local-fs.target
内容也很好看懂。Requires、After 这和 systemd service 的写法基本一致(其实我也不太懂),[Mount] 下就是挂载的说明了,What 后是要挂载的文件系统,Where 是挂载到的地方,Type 是文件系统类型,Options 是挂载参数。相当于:
mount -t <Type> -o <Options> <What> <Where>
不知道有人注意到这个文件名没,尤其是第一个。sfs-usr_share-ro.mount 这样命名其实是 systemd 强制要求的(抄自 man systemd.mount):
反正就是要和你挂载到的路径一致,把路径里的「/」换成「 -」。挺蛋疼的。
其实现在重启应该就可以了,/usr/share 放那儿反正会被 mount 盖掉。重启后确认 /usr/share 确实挂上 aufs 了,原来的文件是否删除就看心情了吧。
说句实话,给 Debian stable 之类的上这个优化可能更有效。Arch 你得经常滚啊,滚一滚 aufs 可写分支就变得很大,这时就得重新压一下 squashfs 了。
重新压的步骤和前面差不多,就是把你现在的 /usr/share 当成没压的重新压一遍,把可写分支清空。不过清空可写分支的操作得离线进行(至少要进 single 模式卸载掉原来的 aufs)。注意安全,不多说了。
随便写写,没看懂的人千万不要乱试哦!