Linux Swap詳解


 

 

什么是Linux swap space呢?我們先來看看下面兩段關於Linux swap space的英文介紹資料:

 

Linux divides its physical RAM (random access memory) into chucks of memory called pages. Swapping is the process whereby a page of memory is copied to the preconfigured space on the hard disk, called swap space, to free up that page of memory. The combined sizes of the physical memory and the swap space is the amount of virtual memory available.

Swap space in Linux is used when the amount of physical memory (RAM) is full. If the system needs more memory resources and the RAM is full, inactive pages in memory are moved to the swap space. While swap space can help machines with a small amount of RAM, it should not be considered a replacement for more RAM. Swap space is located on hard drives, which have a slower access time than physical memory.Swap space can be a dedicated swap partition (recommended), a swap file, or a combination of swap partitions and swap files.

 

Linux內核為了提高讀寫效率與速度,會將文件在內存中進行緩存,這部分內存就是Cache Memory(緩存內存)。即使你的程序運行結束后,Cache Memory也不會自動釋放。這就會導致你在Linux系統中程序頻繁讀寫文件后,你會發現可用物理內存變少。當系統的物理內存不夠用的時候,就需要將物理內存中的一部分空間釋放出來,以供當前運行的程序使用。那些被釋放的空間可能來自一些很長時間沒有什么操作的程序,這些被釋放的空間被臨時保存到Swap空間中,等到那些程序要運行時,再從Swap分區中恢復保存的數據到內存中。這樣,系統總是在物理內存不夠時,才進行Swap交換。

 

 

在Linux下,SWAP的作用類似Windows系統下的“虛擬內存”。當物理內存不足時,拿出部分硬盤空間當SWAP分區(虛擬成內存)使用,從而解決內存容量不足的情況。

 

SWAP意思是交換,顧名思義,當某進程向OS請求內存發現不足時,OS會把內存中暫時不用的數據交換出去,放在SWAP分區中,這個過程稱為SWAP OUT。當某進程又需要這些數據且OS發現還有空閑物理內存時,又會把SWAP分區中的數據交換回物理內存中,這個過程稱為SWAP IN。

當然,swap大小是有上限的,一旦swap使用完,操作系統會觸發OOM-Killer機制,把消耗內存最多的進程kill掉以釋放內存

 

 

數據庫系統為什么嫌棄swap?

 

顯然,swap機制的初衷是為了緩解物理內存用盡而選擇直接粗暴OOM進程的尷尬。但坦白講,幾乎所有數據庫對swap都不怎么待見,無論MySQL、Oracal、MongoDB抑或HBase,為什么?這主要和下面兩個方面有關:

 

1. 數據庫系統一般都對響應延遲比較敏感,如果使用swap代替內存,數據庫服務性能必然不可接受。對於響應延遲極其敏感的系統來講,延遲太大和服務不可用沒有任何區別,比服務不可用更嚴重的是,swap場景下進程就是不死,這就意味着系統一直不可用……再想想如果不使用swap直接oom,是不是一種更好的選擇,這樣很多高可用系統直接會主從切換掉,用戶基本無感知。

 

2. 另外對於諸如HBase這類分布式系統來說,其實並不擔心某個節點宕掉,而恰恰擔心某個節點夯住。一個節點宕掉,最多就是小部分請求短暫不可用,重試即可恢復。但是一個節點夯住會將所有分布式請求都夯住,服務器端線程資源被占用不放,導致整個集群請求阻塞,甚至集群被拖垮。

 

從這兩個角度考慮,所有數據庫都不喜歡swap還是很有道理的!

 

 

 

swap的工作機制

 

既然數據庫們對swap不待見,那是不是就要使用swapoff命令關閉磁盤緩存特性呢?非也,大家可以想想,關閉磁盤緩存意味着什么?實際生產環境沒有一個系統會如此激進,要知道這個世界永遠不是非0即1的,大家都會或多或少選擇走在中間,不過有些偏向0,有些偏向1而已。很顯然,在swap這個問題上,數據庫必然選擇偏向盡量少用。HBase官方文檔的幾點要求實際上就是落實這個方針:盡可能降低swap影響。知己知彼才能百戰不殆,要降低swap影響就必須弄清楚Linux內存回收是怎么工作的,這樣才能不遺漏任何可能的疑點。

 

 

 

先來看看swap是如何觸發的?

 

 

 

簡單來說,Linux會在兩種場景下觸發內存回收,一種是在內存分配時發現沒有足夠空閑內存時會立刻觸發內存回收;一種是開啟了一個守護進程(swapd進程)周期性對系統內存進行檢查,在可用內存降低到特定閾值之后主動觸發內存回收。第一種場景沒什么可說,來重點聊聊第二種場景,如下圖所示:

 

 

 

 

Linux swap相關命令:

 

swapoff -a //停止所有的swap分區
sudo swapoff -v /swapfile //關閉某個分區
swapoff -a //關閉所有swap空間 (包含磁盤、文件)

swapon -a //開啟所有swap空間(已經配置到/etc/fstab文件中的)
swapon -s // 顯示交換分區的簡要信息
free -m //查看swap空間大小
sysctl -q vm.swappiness //查詢swap優先級
sudo sysctl vm.swappiness=10 //修改swap優先級,注:即使將值設為0,也並不會禁用swap,只是盡可能少用swap,多用實際內存。

 

 

 

 

 

查看Swap分區大小

 

 

 

查看Swap分區的大小以及使用情況,一般使用free命令即可,如下所示,Swap大小為2015M,目前沒有使用Swap分區

 

[root@DB-Server ~]# free -m

             total       used       free     shared    buffers     cached

Mem:          1000        855        145          0         28        296

-/+ buffers/cache:        530        470

Swap:         2015          0       2015

 

 

 

 

另外我們還可以使用swapon命令查看當前swap相關信息:例如swap空間是swap partition,Swap size,使用情況等詳細信息

 

[root@DB-Server ~]# swapon -s

Filename                                Type            Size    Used    Priority

/dev/sda3                               partition       2064344 0       -1

[root@DB-Server ~]# cat /proc/swaps

Filename                                Type            Size    Used    Priority

/dev/sda3                               partition       2064344 0       -1

[root@DB-Server ~]# 

 

 

如圖:

 

 

clip_image001

 

 

 

Swap分區大小設置

 

 

 

系統的Swap分區大小設置多大才是最優呢? 關於這個問題,應該說只能有一個統一的參考標准,具體還應該根據系統實際情況和內存的負荷綜合考慮,像ORACLE的官方文檔就推薦如下設置,這個是根據物理內存來做參考的。

 

RAM

Swap Space

Up to 512 MB

2 times the size of RAM

Between 1024 MB and 2048 MB

1.5 times the size of RAM

Between 2049 MB and 8192 MB

Equal to the size of RAM

More than 8192 MB 

 0.75 times the size of RAM

 

另外在其它博客中看到下面一個推薦設置,當然我不清楚其怎么得到這個標准的。是否合理也無從考證。可以作為一個參考。

 

4G以內的物理內存,SWAP 設置為內存的2倍。

 

4-8G的物理內存,SWAP 等於內存大小。

 

8-64G 的物理內存,SWAP 設置為8G。

 

64-256G物理內存,SWAP 設置為16G。

 

上下兩個標准確實也很讓人無所適從。我就有一次在一台ORACLE數據庫服務器(64G的RAM),按照官方推薦設置了一個很大的Swap分區,但是我發現其實這個Swap幾乎很少用到,其實是浪費了磁盤空間。所以如果根據系統實際情況和內存的負荷綜合考慮,其實應該按照第二個參考標准設置為8G即可。當然這個只是個人的一些認知。

 

 

釋放Swap分區空間

 

[root@testlnx ~]# free -m

             total       used       free     shared    buffers     cached

Mem:         64556      55368       9188          0        926      51405

-/+ buffers/cache:       3036      61520

Swap:        65535         13      65522

[root@testlnx ~]# swapon -s

Filename                                Type            Size    Used    Priority

/dev/mapper/VolGroup00-LogVol01         partition       67108856        14204   -1

 

使用swapoff關閉交換分區

 

[root@testlnx ~]# swapoff /dev/mapper/VolGroup00-LogVol01

 

使用swapon啟用交換分區,此時查看交換分區的使用情況,你會發現used為0了

 

[root@testlnx ~]# swapon /dev/mapper/VolGroup00-LogVol01

[root@testlnx ~]# free -m

             total       used       free     shared    buffers     cached

Mem:         64556      55385       9171          0        926      51406

-/+ buffers/cache:       3052      61504

Swap:        65535          0      65535

[root@testlnx ~]#

 

 

wap分區空間什么時候使用

 

 

系統在什么情況或條件下才會使用Swap分區的空間呢? 其實是Linux通過一個參數swappiness來控制的。當然還涉及到復雜的算法。

這個參數值可為 0-100,控制系統 swap 的使用程度。高數值可優先系統性能,在進程不活躍時主動將其轉換出物理內存。低數值可優先互動性並盡量避免將進程轉換處物理內存,並降低反應延遲。默認值為 60。注意:這個只是一個權值,不是一個百分比值,涉及到系統內核復雜的算法。關於該參數請參考這篇文章[轉載]調整虛擬內存,在此不做過多贅述。下面是關於swappiness的相關資料

 

The Linux 2.6 kernel added a new kernel parameter called swappiness to let administrators tweak the way Linux swaps. It is a number from 0 to 100. In essence, higher values lead to more pages being swapped, and lower values lead to more applications being kept in memory, even if they are idle. Kernel maintainer Andrew Morton has said that he runs his desktop machines with a swappiness of 100, stating that "My point is that decreasing the tendency of the kernel to swap stuff out is wrong. You really don't want hundreds of megabytes of BloatyApp's untouched memory floating about in the machine. Get it out on the disk, use the memory for something useful."

Swappiness is a property of the Linux kernel that changes the balance between swapping out runtime memory, as opposed to dropping pages from the system page cache. Swappiness can be set to values between 0 and 100 inclusive. A low value means the kernel will try to avoid swapping as much as possible where a higher value instead will make the kernel aggressively try to use swap space. The default value is 60, and for most desktop systems, setting it to 100 may affect the overall performance, whereas setting it lower (even 0) may improve interactivity (by decreasing response latency.

 

有兩種臨時修改swappiness參數的方法,系統重啟后失效

方法1:

[root@DB-Server ~]# more /proc/sys/vm/swappiness

60

[root@DB-Server ~]# echo 10 > /proc/sys/vm/swappiness

[root@DB-Server ~]# more /proc/sys/vm/swappiness

10

 

方法2

[root@DB-Server ~]#sysctl vm.swappiness=10

 

永久修改swappiness參數的方法就是在配置文件/etc/sysctl.conf里面修改vm.swappiness的值,然后重啟系統

echo 'vm.swappiness=10' >>/etc/sysctl.conf

 

如果有人會問是否物理內存使用到某個百分比后才會使用Swap交換空間,可以明確的告訴你不是這樣一個算法,如下截圖所示,及時物理內存只剩下8M了,但是依然沒有使用Swap交換空間,而另外一個例子,物理內存還剩下19G,居然用了一點點Swap交換空間。

 

 

如圖:

 

 

外調整/proc/sys/vm/swappiness這個參數,如果你沒有絕對把握,就不要隨便調整這個內核參數,這個參數符合大多數情況下的一個最優值。

 

Swap交換分區對性能的影響

 

我們知道Linux可以使用文件系統中的一個常規文件或獨立分區作為Swap交換空間,相對而言,交換分區要快一些。但是和RAM比較而言,Swap交換分區的性能依然比不上物理內存,目前的服務器上RAM基本上都相當充足,那么是否可以考慮拋棄Swap交換分區,是否不需要保留Swap交換分區呢?這個其實是我的疑問之一。在這篇What Is a Linux SWAP Partition, And What Does It Do?博客中,作者給出了swap交換空間的優劣

Advantages:

 

  1. Provides overflow space when your memory fills up completely
  2. Can move rarely-needed items away from your high-speed memory
  3. Allows you to hibernate

Disadvantages:

 

  1. Takes up space on your hard drive as SWAP partitions do not resize dynamically
  2. Can increase wear and tear to your hard drive
  3. Does not necessarily improve performance (see below)

其實保留swap分區概括起來可以從下面來看:

首先,當物理內存不足以支撐系統和應用程序(進程)的運作時,這個Swap交換分區可以用作臨時存放使用率不高的內存分頁,把騰出的內存交給急需的應用程序(進程)使用。有點類似機房的UPS系統,雖然正常情況下不需要使用,但是異常情況下, Swap交換分區還是會發揮其關鍵作用。

其次,即使你的服務器擁有足夠多的物理內存,也有一些程序會在它們初始化時殘留的極少再用到的內存分頁內容轉移到 swap 空間,以此讓出物理內存空間。對於有發生內存泄漏幾率的應用程序(進程),Swap交換分區更是重要,因為誰也不想看到由於物理內存不足導致系統崩潰。

最后,現在很多個人用戶在使用Linux,有些甚至是PC的虛擬機上跑Linux系統,此時可能常用到休眠(Hibernate),這種情況下也是推薦划分Swap交換分區的。

其實少量使用Swap交換空間是不會影響性能,只有當RAM資源出現瓶頸或者內存泄露,進程異常時導致頻繁、大量使用交換分區才會導致嚴重性能問題。另外使用Swap交換分區頻繁,還會引起kswapd0進程(虛擬內存管理中, 負責換頁的)耗用大量CPU資源,導致CPU飆升。

關於Swap分區的優劣以及是否應該舍棄,我有點惡趣味的想到了這個事情:人身上的兩個器官,闌尾和扁桃體。切除闌尾或扁桃體是否也是爭論不休。另外,其實不要Swap交換分區,Linux也是可以正常運行的(有人提及過這個問題)

 

調整Swap分區的大小

如下測試案例所示,Swap分區大小為65535M,我現在想將Swap分區調整為8G,那么我們來看看具體操作吧

1:查看Swap的使用情況以及相關信息

 

[root@getlnx14uat ~]# swapon -s

Filename                                Type            Size    Used    Priority

/dev/mapper/VolGroup00-LogVol01         partition       67108856        878880  -1

[root@getlnx14uat ~]# free -m

             total       used       free     shared    buffers     cached

Mem:          3957       3920         36          0         39       3055

-/+ buffers/cache:        825       3132

Swap:        65535        858      64677

 

2: 關閉Swap交換分區

 

 

[root@getlnx14uat ~]# swapoff /dev/mapper/VolGroup00-LogVol01

[root@getlnx14uat ~]# swapon -s

Filename                                Type            Size    Used    Priorit

 

 

 

3: 這里是縮小Swap分區大小,如果是增大Swap分區大小,那么就需要擴展正在使用的swap分區的邏輯卷,此處使用lvreduce命令收縮邏輯卷。

 

 

[root@getlnx14uat ~]# lvreduce -L 8G /dev/mapper/VolGroup00-LogVol01

  WARNING: Reducing active logical volume to 8.00 GB

  THIS MAY DESTROY YOUR DATA (filesystem etc.)

Do you really want to reduce LogVol01? [y/n]: y

  Reducing logical volume LogVol01 to 8.00 GB

  Logical volume LogVol01 successfully resized

 

 

 

 

4:格式化swap分區

 

Setting up swapspace version 1, size = 8589930 kB

 

5:啟動swap分區,並增加到/etc/fstab自動掛載

 

Filename                                Type            Size    Used    Priority
[root@getlnx14uat ~]# swapon -s
/dev/mapper/VolGroup00-LogVol01         partition       8388600 0       -1

 

 

如圖:

 

 

linux swap空間的swappiness=0

 

linux 會使用硬盤的一部分做為SWAP分區,用來進行進程調度--進程是正在運行的程序--把當前不用的進程調成‘等待(standby)‘,甚至‘睡眠(sleep)’,一旦要用,再調成‘活動(active)’,睡眠的進程就躺到SWAP分區睡大覺,把內存空出來讓給‘活動’的進程。
  

如果內存夠大,應當告訴 linux 不必太多的使用 SWAP 分區, 可以通過修改 swappiness 的數值。swappiness=0的時候表示最大限度使用物理內存,然后才是 swap空間,swappiness=100的時候表示積極的使用swap分區,並且把內存上的數據及時的搬運到swap空間里面。

在linux里面,默認設置swappiness這個值等於60。

 

現在一般1個G的內存可修改為10, 2個G的可改為5, 甚至是0。具體這樣做:

  1.查看你的系統里面的swappiness
  $ cat /proc/sys/vm/swappiness
  不出意外的話,你應該看到是 60
  2.修改swappiness值為10
  $ sudo sysctl vm.swappiness=10
  但是這只是臨時性的修改,在你重啟系統后會恢復默認的60,為長治久安,還要更進一步:
  $ sudo gedit /etc/sysctl.conf
  在這個文檔的最后加上這樣一行:
  vm.swappiness=10
  然后保存,重啟。ok,你的設置就生效了。 

 

一般來說,Linux的虛擬內存會根據系統負載自動調整。內存頁(page)swap到磁盤會顯著的影響Kafka的性能,並且Kafka重度使用page cache,如果VM系統swap到磁盤,那說明沒有足夠的內存來分配page cache。

 

避免swap的一種方式是設置swap空間為0。但是,swap會在系統崩潰時提供安全機制,或者會在out of memory的情況下阻止操作系統 kill 掉進程。由於這個原因,推薦 vm.swappiness參數設置為一個非常低的值:1 。這個參數表示 VM系統中的多少百分比用來作為swap空間。

 

另外一種方式是通過內核調節“臟頁”(注:“臟頁”會被刷到磁盤上)。Kafka依賴磁盤I/O性能來提高producer的響應時間。這也是為什么通常優先把log segment功能放在可以快速響應的磁盤中(比如SSD)。這樣使得flush進程把“臟數據”寫入磁盤前,“臟頁”數目就減少了,可以設置vm.dirty_background_ratio(表示占用系統內存的百分比)參數的值為10 以下。大部分應用場景下,vm.dirty_background_ratio設置為 5 就夠用了,要注意了:這個參數值不能設置為 0 ,因為設置為 0 后會引起內核持續刷“臟頁”,使得內核的buffer write功能沒法施展。

 

“臟頁”的總量可以通過vm.dirty_ratio 來改變,默認值是 20 (此處也是百分比),這個值的設置范圍較大,一般建議設置 60 到 80 為合理的值。但是vm.dirty_ratio 參數也引來了不小的風險,會造成大量unflush的數據在硬刷到磁盤時產生較長的I/O停頓。如果vm.dirty_ratio 值設置的較大時,強烈建議Kafka開啟備份功能,以備系統崩潰。

 

在設置了這些參數后,需要監控Kafka集群運行時“臟頁”的數量,當前“臟頁”數量可由如下方式查看(/proc/vmstat文件):

 

#cat /proc/vmstat | egrep "dirty|writeback"

nr_dirty 3875

nr_writeback 29

nr_writeback_temp 0

臨時生效:sysctl -w vm.swappiness=0

 

永久生效:

echo "vm.swappiness = 0">> /etc/sysctl.conf (盡量不使用交換分區,注意不是禁用)

 

刷新SWAP

可以執行命令刷新一次SWAP(將SWAP里的數據轉儲回內存,並清空SWAP里的數據)

swapoff -a && swapon -a

sysctl -p (執行這個使其生效,不用重啟)

 

參考:

https://www.cnblogs.com/kerrycode/p/5246383.html

https://www.cnblogs.com/pipci/p/11399250.html

 https://www.cnblogs.com/augusite/p/10784416.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM