VPS 記憶體不夠怎麼辦 – 使用 Swap 空間來解決 Apache 或 MariaDB 當機的問題 | WordPress 技巧

VPS 記憶體不夠怎麼辦 - 使用 Swap 空間來解決 Apache 或 MariaDB 當機的問題 | Wordpress 技巧

增加swap 在自己的伺服器當中

因為電腦時常當機,後來經過神網友回應,才知道是因為記憶體不夠所以 Apache 和 MariaDB 一直崩潰。但是增加記憶體的大小的話主機價格,只要增加一些就會變得非常貴,故我們將會用 Swap 這個東西,把部分硬碟容量變成暫存資料的地方,以減輕我們系統的負擔。

Swap 是類似記憶體的一個東西,會把資料進行站存放在硬碟當中,但因為是硬碟,讀取速度並不會比記憶體快,不過對於解決記憶體容量不足還是有一定的影響力。

以一個小型部落格 8GB 的硬碟容量是非常足夠的,但我建議先預設加到 14 GB 左右,最多預計會用 3GB 的硬碟容量轉換成 Swap 空間。

另外如果你是使用 Linode 架設網站的話,在新建一個新的系統時,Linode 後台就會要求你輸入要建立多大的 Swap ,以預設的大小來說是足夠使用的(預設會有 2GB)。

我的 Apache 或 MariaDB 一直掛掉

[Thu Feb 01 09:06:37.658549 2018] [:notice] [pid 14882:tid 139839034627968] FastCGI: process manager initialized (pid 14882)
[Thu Feb 01 09:06:37.827999 2018] [mpm_worker:notice] [pid 1421:tid 139839034627968] AH00292: Apache/2.4.18 (Ubuntu) mod_fastcgi/mod_fastcgi-SNAP-0910052141 mod_fcgid/2.3.9 configured -- resuming normal operations
[Thu Feb 01 09:06:37.828029 2018] [core:notice] [pid 1421:tid 139839034627968] AH00094: Command line: '/usr/sbin/apache2'
[Thu Feb 01 09:52:45.816792 2018] [mpm_worker:notice] [pid 1421:tid 139839034627968] AH00295: caught SIGTERM, shutting down
[Thu Feb 01 09:52:46.916666 2018] [mpm_worker:notice] [pid 16125:tid 140348726957952] AH00292: Apache/2.4.18 (Ubuntu) mod_fastcgi/mod_fastcgi-SNAP-0910052141 mod_fcgid/2.3.9 configured -- resuming normal operations
[Thu Feb 01 09:52:46.916747 2018] [core:notice] [pid 16125:tid 140348726957952] AH00094: Command line: '/usr/sbin/apache2'
[Thu Feb 01 09:52:46.918576 2018] [:notice] [pid 16128:tid 140348726957952] FastCGI: process manager initialized (pid 16128)

因為我只有使用 Google Computer Egine 最低等級的 Micro 方案,記憶體只有 600MB,其實只要一不注意,訪客增加,伺服器就很容易掛掉。但是為了省錢,並且聽到一個月 10 萬瀏覽人次的網站用這樣等級的方案是足夠的。後來也發現,其實網站後面的伺服器等級可以不用買那麼高等級,重點是系統調校的問題。

如果有去研究 Apache 或是 Nginx 這類伺服器軟體的話,其實他們的邏輯是這樣子的。可以設定最多有多少的工作 process,而每個 prcess 可以用多少的記憶體,並可且可以活多久。
但是 MySQL 或是 MariaDB 並不是這個邏輯在跑,有些指令在跑的時候會在短時間內使用大量的記憶體,而這個也是 Apache 無法控制的。

例如你有 600 MB 的記憶體,分個 11 個 process 去跑,這樣每個人會有 50 MB 可以跑。Apache 雖然可以控制 Wordpess 使用多少記憶體,但是當 WordPress 執行 MySQL 時,MySQL 本身會在短時間內吃掉大量記憶體,所以可能會出現「資料庫無法連線」或是「502」等的錯誤。一下子是 Apache,一下子是 MySQL 掛掉,而且還要考量 Ubuntu 本身還會吃記憶體。

觀察系統的容量使用:swap、硬碟和記憶體狀況

硬碟大小也要夠大,不然我們無法新增 Swap 空間。我們可以透過以下指令確認記憶體的大小。

free -h

結果可以發現,在 Swap 欄位,Swap 是 0。而記憶體大小只有 581MB。

              total        used        free      shared  buff/cache   available
Mem:           581M        217M         59M         12M        305M        152M
Swap:          0B          0B        0B

如果用這個指令可以發現,確實沒有 Swap 的新增。

sudo swapon -s

結果顯示跟上面的是一樣的。確實 Swap 尚未設定並新增。

Filename				Type		Size	Used	Priority

接著我們要新增 Swap 空間了,我們透過這個指令確認硬碟大小看是否有足夠的硬碟空間新增 Swap。

df -lh

結果顯示「/dev/sda1」有 14GB,也就是硬碟最大只有 14GB,而只有被使用 2.6GB。
Swap 大小需要看你的需求,通常建議的起始大小是記憶體的 2 倍多大即可。
我建議在新增硬碟時就要預留 5GB 的空間以防萬一的使用,這樣整個小型部落格硬碟大小,大約會落在 15GB 左右。

Filesystem      Size  Used Avail Use% Mounted on
udev            283M     0  283M   0% /dev
tmpfs            59M  2.1M   57M   4% /run
/dev/sda1        14G  2.6G   11G  20% /
tmpfs           291M     0  291M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           291M     0  291M   0% /sys/fs/cgroup
tmpfs            59M     0   59M   0% /run/user/1000

建立 Swap 空間

接著我們就要開始建立一個 Swap 給我們使用,我們會在「/」根目錄上建立 Swap 檔案。

我們要使用「fallocate」來清出一個 3GB 的大的空間,其實它的概念是新增一個 3GB 大的檔案,裡面全部都是「0」。不要注意,此步驟請考量自己電腦的硬碟速度,否則可能電腦很容易當機。

sudo fallocate -l 3G /swapfile

為了讓除了「root」以外的所有的使用者都無法使用此檔案(為了安全),我們必須要改變此檔案的權限設定。

sudo chmod 600 /swapfile

到這裡可以用這個指令查看,這檔案已經建立,權限也已經變成 600 了。
不過到這裡為止還不夠,電腦還不知道這是一個 Swap,我們要下指令把檔案格式化為 Swap 空間。

sudo mkswap /swapfile

接著使用此指令啟動 Swap 空間。

sudo swapon /swapfile

接著我們要設定每次系統啟動時,都會自動使用 Swap 空間,輸入以下指令。

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

設定 Swap 使用方式

你可以用一些設定去控制多少資料要放到記憶體,多少資料要放到 Swap。
從 0 到 100,表示有多少百分比的資料會從記憶體轉移到 Swap。也就是說,如果數字接近 0,系統會盡量把資料留在記憶體,系統會比較快。如果數字接近 100,這樣系統會把資料盡量轉移到 Swap,系統會變慢。

sudo sysctl vm.swappiness=10

另外,「vfs_cache_pressure」是控制系統記憶體重新快取(Cache pressure)目錄與 inode 檔案的程度,預設是 100,降低數字會減緩重新快取的頻率。

sudo sysctl vm.vfs_cache_pressure=50

但以上都是暫時性的,要在系統檔案裡面寫好永久設定。

sudo echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo echo 'sysctl vm.vfs_cache_pressure=50' | sudo tee -a /etc/sysctl.conf

最後我們在看一次記憶體的狀況。

sudo swapon --show

會發現 Swap 就新增。

NAME      TYPE SIZE   USED PRIO
/swapfile file   3G 643.8M   -2

如果用這個指令來看的話。

free -h

就可以看到 Swap 已經不是零了。

              total        used        free      shared  buff/cache   available
Mem:           581M        217M         59M         12M        305M        152M
Swap:          3.0G          0B        3.0G
參考資料:
1. How To Resolve "Out of Memory" Errors on Ubuntu 17.10
2. Linux 的記憶體快取(Cache Memory)功能:Linux 系統把記憶體用光了? - G. T. Wang
3. Ubuntu 16.04 建立 Swap file & 調校 swap  | Mr. 沙先生
4. How To Add Swap Space on Ubuntu 16.04 | DigitalOcean
5. How to Enable Or Add Swap Space on Ubuntu 16.04