當剩餘大量可用記憶體時,為什麼要使用 Swap?

當剩餘大量可用記憶體時,為什麼要使用 Swap?

我有很好的網路(專用)伺服器,具有良好的記憶體資源:

System information
Server load     2.19 (8 CPUs)   
Memory Used     29.53% (4,804,144 of 16,267,652)    
Swap Used   10.52% (220,612 of 2,097,136)   

正如您所看到的,當有足夠的可用記憶體時,我的伺服器正在使用交換。

這是正常現象還是配置或編碼有問題?

注意:
出於某種原因,我的 MySQL 進程使用了超過 160% 的 CPU 能力;我不知道為什麼,但我沒有超過 70 個並髮用戶...

答案1

這是完全正常的。

系統啟動時,會啟動許多服務。這些服務會自行初始化、讀取設定檔、建立資料結構等。他們使用一些記憶體。其中許多服務在系統啟動期間將永遠不會再次運行,因為您沒有使用它們。其中一些可能會在數小時、數天或數週內運行。然而所有這些數據都在物理記憶體中。

當然,系統不能丟棄這些數據。它不能證明它實際上永遠不會被訪問。例如,其中一項服務可能是為您提供對盒子的遠端存取的服務。您可能一周沒有使用它,但如果您使用它,它的效果會更好。

但係統知道它可能希望將該實體記憶體用於磁碟快取或其他可以提高效能的方式。所以它會進行機會主義交換。當它無事可做時,它會使用交換空間將很長時間未使用的資料寫入磁碟。但是,它仍然將頁面保留在實體記憶體中。因此,仍然可以訪問它們,而無需交換它們。

現在,如果系統稍後需要該實體記憶體用於其他用途,它可以簡單地丟棄這些頁面,因為它已經將它們寫入交換。這使得該系統兩全其美。資料仍然保存在記憶體中,因此無需從磁碟讀取即可存取。但如果系統需要該記憶體用於其他目的,則不必先寫出。到處都是大勝利。

答案2

如果過去某個時間您需要的記憶體多於機器中的實體 RAM,則可能會發生這種情況。此時一些資料將被寫入交換空間。

當稍後記憶體被釋放時,交換區中的資料不會自動讀回 RAM:只有當某些進程實際需要交換區中的資料時才會發生這種情況。這是完全正常的。

至於你的 mysql 進程:這一切都取決於你執行的查詢類型。理論上,無論使用者數量多少,2 個非常複雜的查詢可能足以獲得這樣的負載。您可以啟用慢查詢日誌來更深入地了解哪些查詢是負載密集的。

答案3

您也可以透過 更改此行為sysctl -w vm.swappiness=10,這將大大減少交換的使用,直到實際需要為止。

對於 MySQL,您是否至少使用以下命令執行過基線設定測試:調整底漆.sh腳本?

答案4

正如 David 所解釋的那樣,這可能是 Linux 核心的正常行為,但也可能是由於MySQL「交換瘋狂」問題。在您的情況下(8 個CPU,總共16 GB RAM,使用5 GB),為此,您的電腦應該是一個NUMA 系統,具有4 個節點(插槽),每個節點有4 GB RAM,並且MySQL InnoDB 緩衝池為 4 GB。

簡而言之(您應該閱讀上面的連結以獲取完整的詳細資訊),發生的情況如下:

  1. 當系統啟動時,進程會使用部分記憶體分佈在所有 NUMA 節點上。
  2. 當MySQL啟動時,它為InnoDB緩衝池分配4GB,填充NUMA節點的RAM並使用其他節點上的一些RAM。
  3. 然後,Linux 核心無法將分配的 RAM 從一個 NUMA 節點移動到另一個 NUMA 節點,它認為從飢餓節點換出頁面是個好主意(或者需要換出頁面,因為需要換入頁面)。

為了避免這種情況,請更改 MySQL 的記憶體分配以在所有核心上分配 RAM(有關更多詳細信息,請參閱上面的連結)。

相關內容