Linux交換空間(swap space)

每次安裝Linux的時候,都會要求配置交換分區,那麼這個分區是幹嗎的呢?不設置這個分區有什麼後果?若是必定要設置,設置多大比較合適?本篇將試圖回答這些問題並儘可能覆蓋全部swap相關的知識。linux

下面的全部例子都在ubuntu-server-x86_64 16.04下執行經過算法

什麼是swap?

swap space是磁盤上的一塊區域,能夠是一個分區,也能夠是一個文件,或者是他們的組合。簡單點說,當系統物理內存吃緊時,Linux會將內存中不常訪問的數據保存到swap上,這樣系統就有更多的物理內存爲各個進程服務,而當系統須要訪問swap上存儲的內容時,再將swap上的數據加載到內存中,這就是咱們常說的swap out和swap in。ubuntu

爲何須要swap?

要回答這個問題,就須要回答swap給咱們帶來了哪些好處。segmentfault

  • 對於一些大型的應用程序(如LibreOffice、video editor等),在啓動的過程當中會使用大量的內存,但這些內存不少時候只是在啓動的時候用一下,後面的運行過程當中不多再用到這些內存。有了swap後,系統就能夠將這部分不這麼使用的內存數據保存到swap上去,從而釋放出更多的物理內存供系統使用。bash

  • 不少發行版(如ubuntu)的休眠功能依賴於swap分區,當系統休眠的時候,會將內存中的數據保存到swap分區上,等下次系統啓動的時候,再將數據加載到內存中,這樣能夠加快系統的啓動速度,因此若是要使用休眠的功能,必需要配置swap分區,而且大小必定要大於等於物理內存服務器

  • 在某些狀況下,物理內存有限,但又想運行耗內存的程序怎麼辦?這時能夠經過配置足夠的swap空間來達到目標,雖然慢一點,但至少能夠運行。app

  • 雖然大部分狀況下,物理內存都是夠用的,可是總有一些意想不到的情況,好比某個進程須要的內存超過了預期,或者有進程存在內存泄漏等,當內存不夠的時候,就會觸發內核的OOM killer,根據OOM killer的配置,某些進程會被kill掉或者系統直接重啓(默認狀況是優先kill耗內存最多的那個進程),不過有了swap後,能夠拿swap當內存用,雖然速度慢了點,但至少給了咱們一個去debug、kill進程或者保存當前工做進度的機會。編輯器

  • 若是看過Linux內存管理,就會知道系統會盡量多的將空閒內存用於cache,以加快系統的I/O速度,因此若是能將不怎麼經常使用的內存數據移動到swap上,就會有更多的物理內存用於cache,從而提升系統總體性能。ide

swap的缺點?

上面介紹了swap的優勢,那swap的缺點呢?swap是存放在磁盤上的,磁盤的速度和內存比較起來慢了好幾個數量級,若是不停的讀寫swap,那麼對系統的性能確定有影響,尤爲是當系統內存很吃緊的時候,讀寫swap空間發生的頻率會很高,致使系統運行很慢,像死了同樣,這個時候添加物理內存是惟一的解決辦法。性能

因爲系統會自動將不經常使用的內存數據移到swap上,對桌面程序來講,有可能會致使最小化一個程序後,再打開時小卡一下,由於須要將swap上的數據從新加載到內存中來。

到底要不要swap?

上面介紹了什麼是swap以及它們的優缺點,那麼到底要不要配置swap呢?答案是:看狀況。

下面分別討論內存不夠用、內存勉強夠用和內存很充裕這三種狀況下服務器和桌面環境對swap的選擇。

內存不夠用

無論是桌面仍是服務器,當物理內存明顯不夠用,而又想跑程序的話,添加swap是惟一的選擇,慢點總比不能工做強。

內存勉強夠用

建議配置swap,這樣內核會將不經常使用的數據從內存移到swap上,從而有更多的物理內存供系統調用,提高系統性能,同時也避免因偶爾的物理內存不夠形成進程異常退出,提高系統穩定性,但對服務器來講,必定要限制或者監控swap空間的使用狀況,當出現swap空間使用超預期或者swap in/out頻繁時,要及時採起措施,否則對性能影響很大

內存充裕

理論上來講,若是物理內存足夠多而且不須要休眠功能,那swap就沒什麼用,可關鍵問題是咱們很難保證物理內存在任何狀況下都夠用,由於總有意想不到的狀況發生,好比某些進程耗內存超預期,服務器壓力超預期,內存泄漏等。

在內存充裕的這種狀況下,若是發生異常,swap能幫到咱們嗎?

桌面環境

通常不會開什麼監控功能,因此也無法提早預知內存使用異常,當內存被用光的時候,分兩種狀況:

  • 配置了swap:在系統變慢的時候能感受到,可能還有機會殺掉一些進程和保存當前工做進度,固然也會出現慢的想砸電腦的狀況,不過在磁盤如此廉價的狀況下,浪費點磁盤空間換取這樣的一個機會仍是值得的。

  • 沒有配置swap:內核的OOM killer被觸發,可能連保存工做進度的機會都沒有。

服務器環境

服務器通常都會配置監控程序,當內存用量達到一個閾值的時候告警或者會自動重啓異常的進程。但若是沒有監控呢?當內存被用光的時候,分兩種狀況:

  • 配置了swap:這時服務器還能提供服務,但性能會下降好幾個檔次,直到最終處於幾乎死機狀態,而且這一過程將持續很長一段時間,對服務器來講是個災難;因此配置swap只能讓服務再苟延殘喘一下子,而後就是長時間的服務中斷(好比原來是每秒處理1000個請求的服務器,因爲頻繁使用swap,致使如今每秒只能處理50個請求,站在系統角度,進程還在運行,可是在業務角度服務已經幾乎中斷了)。

  • 沒配置swap:這時內核的OOM killer被觸發,在默認配置下,耗內存的進程會被優先kill掉,這種進程通常就是咱們的業務進程,這時守護進程就會自動重啓該業務進程(沒有守護進程?開什麼玩笑),這種狀況只會形成服務中斷一會會兒(取決於進程重啓的時間),不會出現上面因配置了swap而致使性能不好且服務持續中斷的狀況。就算OOM killer沒有kill掉預期的進程,咱們經過測試也能發現,而後將OOM killer配置成重啓系統,那也比配置了swap在那裏苟延殘喘的好。

從上面能夠看出,對服務器來講,彷佛不配置swap更好,可讓有問題的進程儘快重啓,縮短業務受影響的時間。

而且,就算沒有配置監控程序,咱們還有cgroups中的內存控制模塊,能夠控制一組進程所能使用的最大內存數,當超過這個數的時候,能夠觸發相應的行爲,好比重啓進程等。

總的來講,對於桌面環境來講,通常內存沒有服務器端那麼充裕,而且因爲使用場景緣由,會打開不少不一樣類型的GUI窗口,但前臺的進程只有一個,大部分都是在後臺待命,因此配置swap對提高性能仍是有必要的;對於服務器來講,配置的內存都比較充裕,啓動起來的進程也都是要幹活的進程(否則就不該該被啓動起來),而且也沒有休眠的需求,再加上有了cgroups以後,能夠更輕鬆的限制進程的內存使用,我的認爲配置swap基本沒什麼必要了,看看coreos,默認就沒有swap。

swap大小配置多少比較合適?

既然配置swap對桌面系統有幫助,那麼配置多少大小的swap比較合適呢?下面是ubuntu給出的建議:

  • 當物理內存小於1G且不須要休眠時,設置和內存一樣大小的swap空間便可;當須要休眠時,建議配置兩倍物理內存的大小,但最大值不要超過兩倍內存大小

  • 當物理內存大於1G且不須要休眠時,建議大小爲round(sqrt(RAM)),其中RAM爲物理內存大小;當須要休眠時,建議大小是RAM+round(sqrt(RAM)),但最大值不要超過兩倍內存大小

  • 若是兩倍物理內存大小的swap空間還不夠用,建議增長內存而不是增長swap

下面是詳細的不一樣物理內存狀況下的建議,第一列是物理內存的大小,第二列和第三列是不須要和須要休眠兩種狀況下推薦的大小,第四列是不要超過的最大值

物理內存(MB)  不須要休眠  須要休眠  最大值
 256          256       512     512
 512          512       1024    1024
 1024         1024      2048    2048

物理內存(GB)  不須要休眠  須要休眠  最大值
  1          1         2        2
  2          1         3        4
  3          2         5        6
  4          2         6        8
  5          2         7        10
  6          2         8        12
  8          3         11       16
  12         3         15       24
  16         4         20       32
  24         5         29       48
  32         6         38       64
  64         8         72       128
  128        11       139       256

怎麼配置swap?

當咱們肯定好配置多大的swap空間後,具體應該怎麼配置呢?固然能夠在系統安裝的時候分配好,但若是對安裝時分配的大小不滿意,咱們還能夠在後面進行調整。在這裏將不介紹安裝的時候怎麼配,只介紹如何往系統中添加更多的swap空間。

Linux下有兩種類型的swap空間,swap分區和swap文件,他們有各自的特色:

  • swap分區上面因爲沒有文件系統,因此至關於內核直接訪問連續的磁盤空間,效率相對要高點,但因爲swap分區通常安裝系統時就分配好了了,後期要縮減空間和擴容都很不方便。

  • swap文件放在指定分區的文件系統裏面,因此有可能受文件系統性能的影響,但聽說2.6版本之後的內核能夠直接訪問swap文件對應的物理磁盤地址,至關於跳過了文件系統直接訪問磁盤,不過若是swap文件在磁盤上的物理位置不連續時,仍是會對性能產生不利影響,但其優勢就是靈活,隨時能夠增長和移除swap文件。

查看系統中已經配置的swap

使用命令swapon -s便可查看系統中在用的swap

dev@dev:~$ swapon -s
Filename                Type        Size    Used    Priority
/dev/dm-1               partition   524284  0       -1

若是配置有多個swap分區或者文件的話,這裏將會有多行,每行表明一個正在被系統使用的swap分區或文件,下面是每一個字段的意思:

  • Filename:若是swap類型是分區,這裏將是分區的路徑,若是swap類型是文件,這裏將是文件的路徑

  • Type:swap的類型,partition表明這是一個swap分區,file表明這是一個swap文件

  • Size:swap的大小,單位是k,這裏524284表示的差很少是512M

  • Used:已經被使用的大小,這裏0表示尚未被使用到

  • Priority:優先級,優先級高的swap將會被優先使用,同等優先級的swap將會被均勻的使用(round-robin算法),優先級能夠經過「swapon -p」命令來設置

查看系統中swap in/out的狀況

並非swap空間佔用多就必定性能降低,真正影響性能是swap in和out的頻率,頻率越高,對系統的性能影響越大,咱們能夠經過vmstat命令來查看swap in/out的頻率

#參數2表示每兩秒統計一次,si和so兩列就是每秒swap in和out的次數
dev@ubuntu:~$ vmstat 2
procs------------memory--------------swap----io-----system-----------cpu-----
 r b    swpd  free  buff cache      si so   bi bo   in  cs      us sy id wa st
 0 0    70232 75620 7940 209476     0  0    0  0    111 180     0  1  99 0  0
 0 0    70232 75620 7940 209476     0  0    0  0    116 186     1  1  99 0  0
 0 0    70228 75620 7940 209476     2  0    2  0    120 193     1  1  98 1  0
 0 0    70228 75620 7940 209476     0  0    0  0    117 186     0  0  100 0 0
 0 0    70228 75620 7940 209476     0  0    0  0    113 184     0  1  99 0  0

添加swap分區

在添加swap分區前,首先得有一個空閒的分區,若是是一塊新的磁盤,能夠用fdisk來建立一個新的分區用於swap。

注意:磁盤分區操做必定要當心,弄很差就會形成數據丟失、系統掛掉的後果。磁盤分區操做不是本篇要介紹的內容,因此這裏不會討論fdisk怎麼用。

#本篇使用的測試環境是虛擬機,/dev/sdb是一塊新加的硬盤而且已經用fdisk建立好了一個分區
#本例中將使用/dev/sdb1這個分區
dev@dev:~$ sudo fdisk -l /dev/sdb
Device     Boot Start     End Sectors Size Id Type
/dev/sdb1        2048 4194303 4192256   2G 83 Linux

#建立swap分區
dev@dev:~$ sudo mkswap /dev/sdb1
Setting up swapspace version 1, size = 2 GiB (2146430976 bytes)
no label, UUID=d69621de-618a-4bea-9a96-b8e8b0d0ea40

#查看系統中如今正在使用的swap,以便於和添加後作比較
dev@dev:~$ swapon -s
Filename                Type        Size    Used    Priority
/dev/dm-1                               partition   524284  0   -1

#將新的分區加入到系統中
dev@dev:~$ sudo swapon /dev/sdb1

#這時候能夠看到新的swap分區已經被加入到系統中了,而且優先級比原來的要低
dev@dev:~$ swapon -s
Filename                Type        Size    Used    Priority
/dev/dm-1               partition   524284  0       -1
/dev/sdb1               partition   2096124 0       -2

#爲了保證系統重啓後會自動加載咱們新的swap分區,須要修改/etc/fstab文件
dev@dev:~$ sudo sh -c 'echo "/dev/sdb1 none  swap    sw   0    0" >> /etc/fstab'
#查看一下,確保寫入成功,這裏的第一條是原來的系統的swap分區,第二條是咱們剛添加的
dev@dev:~$ grep swap /etc/fstab
/dev/mapper/dev--vg-swap_1 none            swap    sw              0       0
/dev/sdb1 none  swap    sw   0    0

添加swap文件

添加swap文件就簡單多了,也沒有分區操做那麼有風險。

#先建立一個新的512M的文件,用來做爲swap文件,文件路徑能夠隨便
#fallocate這個命令依賴於文件系統,有些老的文件系統不支持這個命令,好比ext2,
#這種狀況下能夠用dd來實現一樣的效果:
#sudo dd if=/dev/zero of=/mnt/512MiB.swap bs=1024 count=524288
#fallocate和dd的區別在於:
#fallocate是先聲明這麼多,而後在具體用到的時候文件系統才分配真正的物理磁盤空間,就是用一點分配一點,
#而dd是一開始就實實在在的寫了512m的數據到物理磁盤空間。
#因此做爲測試來講fallocate方便些,由於剛開始不用寫任何數據,要快
dev@dev:~$ sudo fallocate -l 512m /mnt/512MiB.swap

#修改文件的權限,避免其餘用戶對這個文件進行誤操做
dev@dev:~$ sudo chmod 600 /mnt/512MiB.swap

#格式化爲swap文件
dev@dev:~$ sudo mkswap /mnt/512MiB.swap

#將新的文件加入到系統中
dev@dev:~$ sudo swapon /mnt/512MiB.swap

#這時候能夠看到新的swap文件已經被加入到系統中了,類型爲file
#這裏能夠看到因爲優先級最高,第一個swap分區/dev/dm-1已經被使用了24K
dev@dev:~$ swapon -s
Filename                Type        Size    Used    Priority
/dev/dm-1               partition   524284  24      -1
/dev/sdb1               partition   2096124 0       -2
/mnt/512MiB.swap        file        524284  0       -3

#從free命令的輸出能夠看到,通過前面兩輪添加swap分區和文件,
#如今系統的交換空間已經變成3G(3144692K)了
dev@dev:~$ free
              total        used        free      shared  buff/cache   available
Mem:         500192       39112        9564        1996      451516      430820
Swap:       3144692          24     3144668

#一樣爲了保證系統重啓後會自動加載咱們新的swap文件,須要修改/etc/fstab文件
dev@dev:~$ sudo sh -c 'echo "/mnt/512MiB.swap none  swap    sw   0    0" >> /etc/fstab'

注意:不是全部的文件系統都支持建立swap文件,如btrfs,在btrfs分區裏建立swap文件將失敗。

取消全部的swap

若是通過深思熟慮以後,肯定再也不須要swap,那麼能夠將全部的swap分區和文件從系統中移除,步驟和上面的恰好相反

#停掉全部系統正在使用的swap
dev@dev:~$ sudo swapoff -a

#swapon -s命令沒有任何輸出,free命令顯示swap空間爲0,說明swapoff成功
dev@dev:~$ swapon -s
dev@dev:~$ free
              total        used        free      shared  buff/cache   available
Mem:         500192       35924      348888        2004      115380      433924
Swap:             0           0           0

#固然咱們還須要修改/etc/fstab,不然下次重啓後,系統又會從新掛載相應的swap分區和文件
#使用本身喜歡的編輯器,將/etc/fstab中跟swap相關的三行刪掉便可(本例中是三行,請根據實際狀況調整)

如何優化swap性能?

怎麼配置swap可讓它的性能更好呢?

  • 儘可能使用swap分區,相對於swap文件來講,分區確定是連續的物理磁盤空間,而swap文件有可能不是

  • 將swap分區和系統所在的分區放在不一樣的磁盤上,這樣就不會和系統盤搶同一個磁盤的I/O帶寬

  • 若是有多塊磁盤的話,能夠在每一個盤上建立一個swap分區,而且將它們的優先級設置的同樣,這樣內核就會平均的訪問這些swap分區,性能至關於原來的N倍(這裏N是磁盤的數量)

不過話又說回來了,若是頻繁的訪問swap的話,怎麼優化swap都沒用,跟內存比仍是低幾個數量級,性能仍是降低的厲害,若是不頻繁訪問swap的話,優化swap又有啥意義呢?因此其實優化swap性能的實際意義不大,這裏瞭解一下就好。

配置swappiness

有時咱們桌面環境確實配置了比較充裕的內存,而且也配置了swap空間,這個時候就但願儘可能減小swap空間的使用,避免對系統性能形成影響,Linux早就幫咱們考慮到這種狀況了,在2.6內核中,增長了一個叫作swappiness的參數,用於配置須要將內存中不經常使用的數據移到swap中去的緊迫程度。這個參數的取值範圍是0~100,0告訴內核儘量的不要將內存數據移到swap中,也即只有在無可奈何的狀況下才這麼作,而100告訴內核只要有可能,儘可能的將內存中不常訪問的數據移到swap中。

Ubuntu的desktop和server的默認配置都是60(可能會隨着版本變化),對於桌面環境來講,界面的響應速度直接關係到系統的流暢程度,若是內存比較充裕的話,能夠將這個值設置的小一點,這樣就儘量的把數據留在內存中,從而喚醒後臺界面程序會更快一些,Ubuntu desktop建議將該值設置爲10,固然你們能夠根據swap空間的實際使用狀況,任意調整這個參數,直到本身滿意的水平爲止。對於服務器來講,主要性能衡量標準是總體的處理能力,而不是具體某一次的響應速度,能把更多的內存用來作I/O cache可能效果更好,因此Ubuntu server建議保持60的默認值。

  • 查看當前系統中swappiness的值

dev@dev:~$ cat /proc/sys/vm/swappiness
60
  • 修改當前系統中swappiness的值

dev@dev:~$ sudo sysctl vm.swappiness=10
vm.swappiness = 10
dev@dev:~$ cat /proc/sys/vm/swappiness
10

上面經過sysctl修改的swappiness值在系統重啓後會失效,要想重啓後繼續生效,須要修改配置文件/etc/sysctl.conf,將下面這行修改爲10,若是文件中找不到這行的話,在文件末位加上這行就能夠了

vm.swappiness=10

參考

相關文章
相關標籤/搜索