放在 Amazon Web Services (AWS) 上的機器因為用途跟價格的關係, ram 的規格開很小,靠 swap 來緩衝的話吃 IO 吃比較兇會被多收錢,想要用 zram 來壓記憶體
zram 的說明可以參考 Wikipedia:http://zh.wikipedia.org/wiki/Zram
zram 是 Linux 核心的一個模組,之前被稱為「compcache」。zram 透過在RAM內的壓縮塊裝置上分頁,直到必須使用硬碟上的交換空間,以避免在磁碟上進行分頁,從而提高效能。由於 zram 可以用記憶體替代硬碟為系統提供交換空間的功能,zram 可以讓 Linux 在需要大量 RAM 的情況下在記憶體上進行交換/分頁,而提高記憶體的使用率,顯著得減少系統啟動時(此時 Linux 還不能使用外部儲存)對記憶體大小的要求。在實體記憶體較少的舊電腦上,尤其如此。
Lubuntu (13.10 開始) 以及 Chrome OS 預設都有啟用這項功能
所以就來安裝 zram-config,沒想到竟然失敗 …
錯誤訊息大概是這樣:
testuser@ubuntu:~$ sudo apt-get install zram-config
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
zram-config
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/3,078 B of archives.
After this operation, 42.0 kB of additional disk space will be used.
Selecting previously unselected package zram-config.
(Reading database ... 107939 files and directories currently installed.)
Unpacking zram-config (from .../zram-config_0.1_all.deb) ...
Processing triggers for ureadahead ...
Setting up zram-config (0.1) ...
start: Job failed to start
invoke-rc.d: initscript zram-config, action "start" failed.
dpkg: error processing zram-config (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
zram-config
E: Sub-process /usr/bin/dpkg returned an error code (1)
從這邊看只知道 post-installation script returned error exit status 1
可能資質比較鈍 … 把 script 挖出來看也沒看出所以然 …
後來看到另一個 script:
https://github.com/gionn/etc/blob/edac27cf705d8ca12d39effa0f80ba62e3907288/init.d/zram
#!/bin/bash
### BEGIN INIT INFO
# Provides: zram
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Increased Performance In Linux With zRam (Virtual Swap Compressed in RAM)
# Description: Adapted from systemd scripts at https://github.com/mystilleef/FedoraZram
### END INIT INFO
DEFAULTS="/etc/default/zram"
# Include defaults if available
[ -r "$DEFAULTS" ] && . "$DEFAULTS"
# Get lsb functions
. /lib/lsb/init-functions
start() {
# Add support of defaults file parameter - ZRAM_NDEVS
if [ -z "$ZRAM_NDEVS" ] || [ "$ZRAM_NDEVS" -le "0" ]; then
# get the number of CPUs
num_cpus=$(grep -c processor /proc/cpuinfo)
else
# or just use user specified
num_cpus=$ZRAM_NDEVS
fi
# if something goes wrong, assume we have 1
[ "$num_cpus" != 0 ] || num_cpus=1
decr_num_cpus=$((num_cpus - 1))
# find module and it's param name
error_file=$(mktemp ${RC_NAME}XXXXXX) # storage for error message
param_name=$(/usr/bin/env modinfo --parameters zram 2>$error_file | head -1 | cut -d: -f1)
error_message=$(<$error_file)
rm -f $error_file
mod_found=$?
# load dependency modules
if [ "$mod_found" == 0 ]; then
log_begin_msg "Loading zRAM kernel module"
modprobe zram "$param_name=$num_cpus"
log_end_msg $?
else
log_failure_msg "Failed to load zRAM kernel module: ${error_message}"
# shit happens, yep.
exit $mod_found
fi
# get the amount of memory in the machine
mem_total_kb=$(fgrep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))
# Add support of defaults file parameter - ZRAM_USE_PERCENT
if [ -z "$ZRAM_USE_PERCENT" ] || [ "$ZRAM_USE_PERCENT" -le "0" ] || [ "$ZRAM_USE_PERCENT" -gt "100" ]; then
# use 100% of ram for zRAM storage (suitable for low-ram laptops)
use_percent=100
else
# or just use user specified
use_percent=$ZRAM_USE_PERCENT
fi
zsize=$((use_percent * mem_total / num_cpus / 100))
# initialize the devices
for i in $(seq 0 $decr_num_cpus); do
echo $zsize > /sys/block/zram$i/disksize
done
# get page size
page_size=$(/usr/bin/env getconf PAGESIZE || /usr/bin/env getconf PAGE_SIZE)
# Creating swap filesystems
for i in $(seq 0 $decr_num_cpus); do
msg="> Making swap on /dev/zram$i"
mkswap -p $page_size /dev/zram$i 2>&1 >/dev/null
[ "$?" -eq "0" ] && log_success_msg $msg || log_failure_msg $msg
done
# Switch the swaps on
for i in $(seq 0 $decr_num_cpus); do
msg=">> Activating swap on /dev/zram$i"
swapon -p 100 /dev/zram$i
[ "$?" -eq "0" ] && log_success_msg $msg || log_failure_msg $msg
done
# TODO FIXME need strict error reporting
# log_end_msg 0
}
stop() {
# Switching off swap ASAP
for zswap in $(fgrep /dev/zram /proc/swaps | cut -d' ' -f1); do
swapoff $zswap
done
# Custom kernels can contain zram compiled-in
[ -z "$(fgrep zram /proc/modules)" ] || rmmod zram
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 3
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
RETVAL=1
esac
把這拿來一用 … 馬上就看到是缺 zram module 了 Orz.. (可參考上方script第50行前後的code): * Loading zRAM kernel module
FATAL: Module zram not found.
原來是 AWS 提供的 Ubuntu image 預設沒有 extra modules,按照 Linux kernel 版本把對應的 extra modules 裝上就行了:
$ sudo apt-get install linux-image-extra-virtual
得到結果:
testuser@ubuntu:~$ sudo apt-get install zram-config
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
zram-config
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/3,078 B of archives.
After this operation, 42.0 kB of additional disk space will be used.
Selecting previously unselected package zram-config.
(Reading database ... 97293 files and directories currently installed.)
Unpacking zram-config (from .../zram-config_0.1_all.deb) ...
Processing triggers for ureadahead ...
Setting up zram-config (0.1) ...
zram-config start/running
來確認一下:
testuser@ubuntu:~$ free -h
total used free shared buffers cached
Mem: 588M 536M 52M 0B 9.3M 338M
-/+ buffers/cache: 188M 400M
Swap: 294M 88K 294M
testuser@ubuntu:~$ cat /proc/swaps
Filename Type Size Used Priority
/dev/zram0 partition 301552 124 5
搞定收工啦!
害我抓了兩台 Ubuntu 13.04 來測試結果是好的, 還把它們升級 13.10 … 一不小心蓋掉了一份資料 … XD