日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Redis - 數據結構和持久化機制

作者:Zong_0915 更新時間: 2022-08-13 編程語言

Redis - 數據結構和持久化機制

  • 前言
  • 一. Redis 底層數據結構
    • 1.1 鍵值之間的組織結構
    • 1.2 哈希沖突和 rehash
      • 1.2.1 漸進式 rehash
    • 1.3 Redis 單線程
      • 1.3.1 Redis 6.0 多線程
    • 1.4 總結
  • 二. Redis 持久化機制
    • 2.1 AOF 日志如何實現快速恢復
      • 2.1.1 AOF 寫回策略
      • 2.1.2 AOF 重寫機制
      • 2.1.3 AOF 阻塞問題
    • 2.2 RDB 如何實現快速恢復
      • 2.2.1 使用RDB案例分析
      • 2.2.2 題外話 - 什么是Swap

前言

Redis這塊的復習,看的是蔣德鈞老師的相關文章,主要是想Redis實戰相關的一些理論知識和解決方案。

Redis是一種典型的鍵值數據庫,即Key-Value形式的一種存儲關系。

Redis是一種內存數據庫,數據都保存在內存上。

一. Redis 底層數據結構

Redis中常見的數據類型有5大類:

  1. String:字符串。
  2. List:列表。
  3. Hash:哈希。
  4. Set:集合。
  5. Sorted Set:有序集合。

Redis中底層的數據結構一共有6大類(實際上也就是Value的存儲形式):

  1. 簡單動態字符串。
  2. 雙向鏈表。
  3. 壓縮列表。
  4. 哈希表。
  5. 跳表。
  6. 整數數組。

兩者的映射關系圖如下:
在這里插入圖片描述
除了String類型,其他的List、Hash、Sorted Set、Set類型統稱為集合類型,一個鍵對應一個集合的數據。

1.1 鍵值之間的組織結構

Redis中使用一個哈希表來保存所有的鍵值對,也因此叫做全局哈希表。

  • 哈希表實際上就是一個數組,由多個哈希桶組成,數組元素就是一個哈希桶。
  • 每個哈希桶又保存了鍵值對數據。
  • 鍵值對數據并不是值本身,而是指向值的指針。 這里無論是key還是value都是存的指針。

如圖:
在這里插入圖片描述

由于Key - Value之間的存儲關系是一個哈希表。因此我們可以用O(1)的時間復雜度來查找到鍵值對。但是,當Redis中寫入的數據量越來越多的時候,操作有可能會突然變慢了,是因為哈希表結構存在著哈希沖突問題以及 rehash操作帶來的操作阻塞。

1.2 哈希沖突和 rehash

我們知道,哈希表中每個哈希桶都會存儲若干個鍵值對(entry),而這些鍵值對存儲于哪一個哈希桶中,由Key的哈希值來決定。那么哈希沖突也就是兩個 key 的哈希值和哈希桶計算對應關系時,正好落在了同一個哈希桶中。

每個哈希桶中元素(entry)之間的組織方式又是什么呢?每個entry之間會通過 next 指針相連,成一個鏈表。就是哈希沖突鏈目的是為了在發生哈希沖突的時候,可以通過哈希沖突鏈進行逐一的元素查找操作。如圖:
在這里插入圖片描述
雖然哈希沖突鏈用于解決哈希沖突,但是我們上文也提到了一個字眼,會根據指針進行逐一的查找,也就是O(N)的一個時間復雜度。因此倘若哈希沖突越嚴重,即同一個哈希桶中的元素越多,那么對應元素的查找時間也就越久。

而這樣的操作對于Redis來說是不可接受的,因為Redis就是追求快,因此Redis此時會對哈希表做rehash操作。也就是增加現有的哈希桶數量,讓entry元素能夠在更多地哈希桶之間分散保存,從而減少單個哈希桶中的元素數量。

Redis準備了兩個全局哈希表,簡稱H1H2平時插入的元素假設都默認使用H1,這時候H2并沒有被分配空間。 當數據到達一定程度,閾值一般是當前哈希表總容量的0.75倍Redis開始執行rehash

rehash的一個大概流程:

  1. H2分配更大的空間,是H1容量的兩倍。
  2. H1中的數據映射并拷貝給H2中。
  3. 釋放掉H1的空間。

下一次rehash以此類推,H1變兩倍… 還需要注意的一點是,在數據的拷貝過程中,如果一次性拷貝所有的數據,會造成Redis線程的阻塞,無法服務其他的請求因此采用了漸進式rehash

1.2.1 漸進式 rehash

漸進式rehash也就是在拷貝數據階段下,Redis每處理一個請求,就會從H1的某個索引位置開始,將該索引對應的哈希桶上的所有entry拷貝到H2中,等下一個請求的時候,則拷貝下一個自然順序的所有entry。如圖:
在這里插入圖片描述

在漸進式rehash的過程中,會同時使用H1H2兩個哈希表,新添加到字典的鍵值對一律會被保存到H2里面,而H1則不再進行任何添加操作,這一措施保證了H1包含的鍵值對數量會只減不增,并隨著rehash操作的執行而最終變成空表。

一句話總結就是:將一次性大量拷貝的過程拆分為多次處理請求的過程中。

最后,我們知道哈希表在查找元素方面的時間復雜度是O(1),而數組和壓縮列表這類數據結構則在O(N),那么為什么Redis還將其作為底層的數據結構呢?原因有兩點:

  1. 內存利用率高:數組和壓縮列表的數據結構比較緊湊,比鏈表的占用空間要更少。而Redis作為內存數據庫,數據都保存在內存上,需要提高內存的利用率。
  2. 數組對CPU高速緩存支持更好:集合數據元素較少情況下,默認采用內存緊湊排列的方式存儲,同時利用CPU高速緩存不會降低訪問速度。當數據元素超過設定閾值后,避免查詢時間復雜度太高,轉為哈希和跳表數據結構存儲,保證查詢效率。

1.3 Redis 單線程

為什么Redis使用單線程去處理呢?首先來說下多線程的優缺點:

  1. 優點:在合理的資源分配情況下,可以增加系統中同一時間內處理請求的個數,即提高吞吐率。
  2. 缺點:同時多線程對共享資源的并發訪問控制,需要有額外的機制進行保證,例如鎖。而這個額外的機制,就會帶來額外的開銷。 有時候控制不好反而會讓效率減低。

因此為了減少多線程帶來的額外開銷和多線程同時訪問共享資源的并發問題,Redis直接采用了單線程模式。

注意:

  • 這里的單線程指的是 Redis 的網絡 IO 和鍵值對讀寫是由一個線程來完成的。
  • 實際上Redis的其他功能,例如持久化、異步刪除、集群數據的同步等操作是由額外的線程執行的。

那么為什么Redis單線程還這么快呢?從上文我們可以得到兩個原因:

  1. Redis是一個內存型數據庫,大部分操作在內存上完成。
  2. 高效的數據結構,哈希表保存鍵值對。跳表加快查詢。

其實還有一個原因就是多路復用機制 IO模型復習傳送門。可以讓其在網路IO操作中能夠并發的處理大量的客戶端請求,實現高吞吐率。

Redis 只運行單線程的情況下,該機制允許內核中,同時存在多個監聽套接字和已連接套接字。內核會一直監聽這些套接字上的連接請求或數據請求。一旦有請求到達,就會交給 Redis 線程處理,這就實現了一個 Redis 線程處理多個 IO 流的效果。

而對于RedisIO模型而言,為了能夠在請求到達的時候能夠及時通知Redis線程,Redis運用了基于事件的回調機制:針對不同的事件,調用對應的處理函數。 如圖:
在這里插入圖片描述
總的來說其流程很簡單:

  1. 客戶端有著不同的請求,而這些請求都作為一個個事件被放入到事件隊列中。
  2. Redis單線程則對該事件隊列不斷進行處理。

再做個小總結,Redis單線程快,快在內存操作哈希和跳表等數據結構多路復用IO機制,但是Redis單線程處理IO請求也有它的性能瓶頸,主要包括兩個方面:

  1. 由于網絡 IO 和鍵值對讀寫是由一個線程來完成的,因此一旦上一個請求阻塞了,后面的請求都要等待前一個耗時請求處理完成,才能夠自己做處理。
  2. 并發量非常大的時候,單線程讀寫客戶端IO存在性能瓶頸,雖然采用IO多路復用機制,但是讀寫客戶端數據依舊是同步IO,只能單線程依次讀取客戶端的數據,無法利用到CPU多核。

耗時操作可能有:

  • 操作超大字符串Key,即bigKeybigKey的寫入和刪除都需要消耗更多的時間,即在分配內存和釋放內存上耗費的時間更久。
  • 使用耗時命令,比如范圍查詢,時間復雜度就是O(N)N越大,越耗時。
  • 大量Key集中過期:因為Redis的過期機制是在主線程中執行的,而大量的Key過期會導致大把時間耗費在Key的刪除上。
  • 淘汰策略:同理,淘汰策略也是在主線程上執行的。
  • AOF刷盤開啟always機制每次寫入都需要把這個操作刷到磁盤,寫磁盤的速度遠比寫內存慢,會拖慢Redis的性能;
  • 主從全量同步生成RDB:雖然采用fork子進程生成數據快照,fork這一瞬間也是會阻塞整個線程的,實例越大,阻塞時間越久。

1.3.1 Redis 6.0 多線程

這里只做介紹和了解:Redis在6.0版本引入了多線程,原因如下:

  • Redis 的瓶頸不在 CPU ,而在內存和網絡,內存不夠可以增加內存或通過數據結構等進行優化。
  • Redis 的網絡 IO 的讀寫占用了部分 CPU 的時間,如果可以把網絡處理改成多線程的方式,性能會有很大提升。(注意:針對客戶端的讀寫是并行的,每個命令的真正操作依舊是單線程的

引入后好處:

  1. 充分利用服務器的多核資源。
  2. 多線程分攤 Redis 同步 IO 讀寫負荷,要么都同時讀,要么都同時寫,沒有同時讀寫的情況。

1.4 總結

5種數據類型,6種數據結構。(左側為數據類型,右側為數據結構組成)

  • String:簡單動態字符串。
  • List:雙向鏈表+壓縮列表。
  • Hash:壓縮列表+哈希表。
  • Set:哈希表+整數數組。
  • Sorted Set:跳表+壓縮列表。

Redis用一個全局的哈希表保存著所有的鍵值對:

  1. 一個哈希表本質上是一個數組,數組的每個元素是一個哈希桶。
  2. 哈希桶中的元素組成一個哈希沖突鏈。即不同的Key計算出的hash值相等
  3. 元素存儲的時候,根據Keyhash值來決定放到哪個哈希桶。
  4. 若發生哈希沖突。則在哈希沖突鏈上逐一查找。

Redis通過漸進rehash的方式,避免哈希沖突太嚴重(目的)。利用兩個全局哈希表來進行數據的漸進拷貝和擴容。


Redis采用單線程模型Redis 的網絡 IO 和鍵值對讀寫是由一個線程來完成的。其快的原因主要有兩點:

  1. Redis是一個內存型數據庫,大部分操作在內存上完成。
  2. 高效的數據結構,哈希表保存鍵值對。跳表加快查詢。

二. Redis 持久化機制

Redis的持久化主要有兩大機制:

  • AOF日志:記錄每次對服務器寫的操作,當服務器重啟的時候會重新執行這些命令來恢復原始的數據。
  • RDB快照:能夠在指定的時間間隔內對你的數據進行快照存儲。

2.1 AOF 日志如何實現快速恢復

我們知道,Mysql中有redo log,都是先寫日志,再將數據寫入磁盤中。即WAL(Write Ahead Log)。這個日志也叫重做日志緩沖,主要是用來實現數據恢復的。而Redis也有個有相同作用的日志:AOF日志。全稱為Append Only File。不過,Mysql不同的是,AOF機制是先將數據寫入內存,再記錄日志。

如圖:
在這里插入圖片描述
AOF日志主要記錄著Redis接收到的每一條指令,以文本形式保存。當Redis宕機時,可以根據AOF日志來恢復內存中的數據。 舉個例子:

set title Hello

那么上述命令對應的AOF日志內容就是:

# 表示該命令由3個部分組成,其中每個部分都以$+數字開頭
*3
# 代表3個字節,后面的同理
$3
set
$5
title
$6
Hello

AOF的優點:

  1. 為了避免額外的檢查開銷RedisAOF做日志記錄的時候,并不會先對命令做語法檢查。而是直接記錄執行成功的命令。
  2. 由于后寫日志,因此并不會阻塞當前的寫操作。

AOF的缺點:

  1. 若執行完一個命令,但在記錄AOF日志之前就發生了宕機,那么這個命令和對應的數據就有丟失的風險。
  2. AOF日志時的主線程阻塞問題。

2.1.1 AOF 寫回策略

為了解決上述的AOF日志缺點,AOF機制提供了三個選項用來控制AOF日志的寫到磁盤的時機

appendfsync always
appendfsync everysec
appendfsync no
  • always:同步寫回。每個寫命令執行完,立馬同步地將日志寫回磁盤。
  • everysec:每秒寫回。每個寫命令執行完,只是先把日志寫到 AOF 文件的內存緩沖區,每隔一秒把緩沖區中的內容寫入磁盤。
  • no:操作系統控制。每個寫命令執行完,同樣先把日志寫到 AOF 文件的內存緩沖區,由操作系統決定何時將緩沖區內容寫回磁盤。

三種寫回策略的優劣勢:

策略 寫回的時機 優點 缺點 選擇 阻塞問題
always 同步寫回,每執行一個命令就寫 高可靠,數據基本不會丟失 每寫一個命令就落盤,性能影響較大 若追求高可靠性保證,選擇它 同步操作是在主進程的主線程中進行的
everysec 每秒寫回 性能折中 若發生宕機,會丟失1秒內的數據 折中 同步操作是通過后臺I/O線程進行的
no 操作系統控制寫回 性能好 若發生宕機,丟失的數據較多 若追求高性能,就選擇它 同步操作的控制權交由操作系統,不阻塞主線程

最后,既然AOF是一種日志的機制,那么不可避免的性能問題就來了:

  • AOF日志的內容越來越多怎么辦?畢竟存儲空間有限。
  • 若文件太大,后面追加命令記錄的時候,效率也會變低。
  • 若發生宕機,難道要對AOF里面的記錄都一條條的執行嗎?效率太低了。

上面歸根到底就是:日志文件太大了怎么辦? 通過AOF重寫機制來解決。

2.1.2 AOF 重寫機制

AOF重寫機制指的是對于過大的AOF文件進行重寫,即壓縮AOF文件的大小。 檢查當前鍵值數據庫中的鍵值對,記錄鍵值對的最終狀態,從而實現對某個鍵值對重復操作后產生的多條操作記錄壓縮成一條的效果。進而實現壓縮AOF文件的大小。

舉個例子:

set title name1;
set title name2;
set title name3;

那么AOF重寫后,對于Keytitle的這個鍵值對,只會記錄最終的結果,即set title name3;

AOF重寫的觸發條件(同時滿足):

  • auto-aof-rewrite-min-size: 表示運行AOF重寫時文件的最小大小,默認為64MB
  • auto-aof-rewrite-percentage:重寫的一個閾值,公式在下面。
    在這里插入圖片描述

2.1.3 AOF 阻塞問題

首先,根據上文我們得知,寫AOF日志的時候,有三種寫回機制,總的來說對應兩種情況:

  • always:由主線程來寫,會阻塞。
  • everysecno:一個是IO線程,一個是系統控制,歸于子進程來執行,不會阻塞主線程。

AOF重寫過程和寫AOF日志過程又不同,重寫過程是由后臺子進程bgrewriteaof來完成的。(注意:AOF重寫和寫AOF日志是兩個東西,不要搞混了)

AOF重寫過程總結為:一個拷貝,兩處日志。

一個拷貝:每次執行重寫的時候,主線程就 fork 出一個后臺 bgrewriteaof 線程,簡稱子進程。子進程會拷貝父進程的頁表,即虛實映射關系,從而共享訪問父進程的內存數據了。


兩處日志:

  • 第一處日志A:當前正在使用的AOF日志:在AOF重寫階段,倘若有新的寫操作,那么Redis就講這個操作寫到日志A的緩沖區。這樣一來即使宕機,該 AOF 日志的操作依舊是完整的,可以用于恢復。
  • 第二處日志B:新的AOF重寫日志。倘若有新的操作也會被寫到該新重寫日志B緩沖區中(注意這里不是寫入日志,而是寫入緩沖區)。這樣一來,日志B也不會丟失最新的操作,重寫完成后,就可以用新的AOF文件代替舊文件了。

AOF工作原理:

  1. Redis 執行 fork() ,現在同時擁有父進程和子進程 bgrewriteaof
  2. 子進程開始將新 AOF 文件的內容寫入到臨時文件。
  3. 對于所有新執行的寫入命令,父進程一邊將它們累積到一個內存緩存中,一邊將這些改動追加到現有 AOF 文件的末尾。這樣樣即使在重寫的中途發生停機,現有的 AOF 文件也還是安全的。
  4. 當子進程完成重寫工作時,它給父進程發送一個信號,父進程在接收到信號之后,將內存緩存中的所有數據追加到新 AOF 文件的末尾。
  5. 最后 Redis 用新文件替換舊文件,之后所有命令都會直接追加到新 AOF 文件的末尾。

流程圖大概如下:
在這里插入圖片描述

總的來說就是:

  1. 用子進程拷貝內存頁表,從而實現父子進程的數據共享。再進行日志的重寫操作。
  2. 重寫階段用兩個AOF日志做記錄,重寫完成后,用新創建的AOF日志替代老的。

問題1:為什么AOF重寫需要用到兩個AOF日志,不能復用AOF日志本身嗎?

回答:

  • 父子進程寫同一個文件必然會產生競爭問題,控制競爭就意味著會影響父進程的性能。
  • AOF重寫過程中失敗了,那么原本的AOF文件相當于被污染了,無法做恢復使用。所以Redis AOF重寫一個新文件,重寫失敗的話,直接刪除這個文件就好了,不會對原先的AOF文件產生影響。等重寫完成之后,直接替換舊文件即可。

問題2:AOF日志重寫的時候,雖然有個子進程,其執行不會阻塞主線程,但是重寫過程就一定不會發生阻塞嗎?

回答:AOF重寫過程中父進程進行寫操作的時候可能會發生阻塞。

從兩個角度來考慮:fork 角度:

  1. 首先主線程fork子進程的時候,一定是阻塞主線程的。fork 采用操作系統提供的寫實復制(Copy On Write)機制,拷貝進程必要的數據結構,包括內存頁表。在拷貝完成之前都是阻塞的。
  2. 因此,阻塞的時間取決于拷貝的內存大小,實例越大,內存頁表越大,fork 時間也就越久。
  3. 拷貝完成后,子進程與父進程指向相同的內存地址空間,父子進程共享一塊數據,但是并沒有申請與父進程相同的內存大小。
  4. 而寫實復制的意思就是在寫操作發生的時候,才會真正拷貝內存真正的數據。

第二點:主進程的寫操作角度:

  1. 若父進程操作的是一個已經存在的key那么這個時候父進程就會真正拷貝這個key對應的內存數據,申請新的內存空間(以頁為單位,默認4K),父子進程內存數據開始分離。
  2. 倘若父進程此時操作的是一個bigkey,根據文章上面的內容可以得知,申請大塊內存的耗時會邊長,從而增加阻塞風險。
  3. 若操作系統開啟了內存大頁機制(Huge Page,頁面大小2M),那么父進程申請內存時阻塞的概率將會大大提高(因為申請大塊內存空間,會很耗時,從而阻塞)。

2.2 RDB 如何實現快速恢復

到這里,我們知道Redis可以通過AOF日志來實現數據的恢復,本質就是執行AOF里面記錄的命令。雖然在命令行很多的情況下,AOF有著重寫機制可以壓縮日志。但是還是得一條條去執行對應的命令,在操作種類繁多的情況下,Redis的恢復速度還是比較慢的。因此又有一種內存快照的方式,所謂內存快照,就是指內存中的數據在某一個時刻的狀態記錄。即RDB,來實現數據的恢復。

AOF相比,RDB記錄的是某一個時刻的全量數據,并不是一條條具體的操作命令了,因此在數據恢復的時候,可以把RDB文件讀入內存中,直接恢復整個數據狀態。不過做RDB快照,也有幾個問題需要去思考:

  • 快照的范圍。
  • 快照過程中,數據是否允許被增刪改,期間Redis是否會被阻塞。

針對第一個問題:快照執行的是全量快照。


針對第二個問題,Redis提供了兩個命令來生成RDB文件:

  • save在主線程中執行,會導致阻塞;
  • bgsave(默認方式):創建一個子進程,專門用于寫入 RDB 文件,避免了主線程的阻塞。

那么快照期間能夠修改數據嗎?答案是可以的。從 2.1 章節中我們得知AOF重寫機制有個fork的過程,子進程和父進程共享內存數據。那么RDB快照的生成也是同理(使用bgsave命令)。

當然,也可以通過配置來設置RDB功能:

# 意思是,如果在60s內,至少有1000個鍵值對的修改,就會觸發bgsave
save 60 1000

bgsave 子進程是由主線程 fork 生成的,可以共享主線程的所有內存數據。bgsave 子進程運行后,開始讀取主線程的內存數據,并把它們寫入 RDB 文件。同樣地,Redis借助寫時復制技術,在執行快照的同時,正常處理寫操作。

那么主子進程之間就是相互獨立的。在主進程開始修改某個數據的時候,大概原理如下:

  1. RDB快照過程中,假設主進程修改了一塊數據,鍵值對M。那么此時這塊數據就會被復制一份,生成對應的副本N
  2. 那么之后主進程主要在副本N上進行數據的操作和修改。
  3. 同時bgsave子進程可以將原來的鍵值對M寫入到RDB文件中。

如圖:
在這里插入圖片描述

那么在了解完RDB的作用以及 RDB可以不阻塞主進程并且不影響讀寫操作之后,我們可以關注于RDB功能的使用時機。雖然 bgsave 執行時不阻塞主線程,但是快照執行的時機卻是一個難題。

  1. 快照間隔過長會丟失數據。
  2. 快照時間過短會加大磁盤寫入壓力。
  3. 頻繁fork子進程 ,fork的過程會導致主進程阻塞。

那么就是說,RDB快照的頻率太高,就會有額外的開銷,太低又可能造成數據的丟失。那咋辦呢?

Redis4.0 中提出了一個混合使用 AOF 日志和內存快照的方法。簡單來說,內存快照以一定的頻率執行,在兩次快照之間,使用 AOF 日志記錄這期間的所有命令操作。 可以通過以下命令開啟:

aof-use-rdb-preamble yes

2.2.1 使用RDB案例分析

題目的搬運(主要這一塊有大佬講解的太好了):

一個 2 核 CPU4GB 內存、500GB 磁盤的云主機運行 RedisRedis 數據庫的數據量大小差不多是 2GB,我們使用了 RDB 做持久化保證。同時Redis主要以寫操作為主,讀寫比例為2:8。那么此時做RDB持久化有什么風險?

內存資源風險:

  1. 因為RDB是由fork子進程做持久化的,而本篇文章提到好多次寫時復制這么個概念。那么在持久化的過程中,寫時復制就會重新分配整個實例80%的內存副本(讀寫比例為2:8)。也就是2GB * 0.8 = 1.6GB。那么此時系統一共就4GB,接近飽和了。
  2. 如果此時父進程又有大量新key寫入,Redis中的數據又是保存到內存中的,所以機器的內存很容易被消耗殆盡。

而這里又可以考慮是否開啟Swap機制:

  • 開啟Swap機制,那么Redis會有一部分數據被換到磁盤上,當Redis訪問這部分在磁盤上的數據時,性能會急劇下降,已經達不到高性能的標準。
  • 沒有開啟Swap機制,會直接觸發OOM,父子進程會面臨被系統kill掉的風險。

CPU資源風險:

  1. 子進程在做生成RDB快照的過程會消耗大量的CPU資源。
  2. 雖然Redis處理處理請求是單線程的,但Redis Server還有其他線程在后臺工作,例如AOF每秒刷盤等這些操作。即其他工作線程還需要占用CPU
  3. 由于機器只有2核CPU,這也就意味著父進程占用了超過一半的CPU資源,此時子進程做RDB持久化,可能會產生CPU競爭,導致的結果就是父進程處理請求延遲增大,子進程生成RDB快照的時間也會變長,整個Redis Server性能下降。

2.2.2 題外話 - 什么是Swap

swap 空間是硬盤上的一塊區域。虛擬內存是由可訪問的物理內存和swap space組成,也即swap space是虛擬內存的一部分。swap存儲那些暫時不活躍的內存頁面。當操作系統決定要給活躍的進程分配物理內存空間并且可利用的物理內存不足時會用到swap space。

說白了,就是把一塊磁盤空間或者一個本地文件,當做內存來使用(重點)。 因此即使服務器的內存不足,也可以運行大內存的應用程序。

原文鏈接:https://blog.csdn.net/Zong_0915/article/details/125981885

欄目分類
最近更新