牛逼!Redis 實(shí)現(xiàn)了自己的 VM……
Redis的VM(虛擬內(nèi)存)機(jī)制就是暫時把不經(jīng)常訪問的數(shù)據(jù)(冷數(shù)據(jù))從內(nèi)存交換到磁盤中,從而騰出寶貴的內(nèi)存空間用于其它需要訪問的數(shù)據(jù)(熱數(shù)據(jù))。
通過VM功能可以實(shí)現(xiàn)冷熱數(shù)據(jù)分離,使熱數(shù)據(jù)仍在內(nèi)存中、冷數(shù)據(jù)保存到磁盤。這樣就可以避免因?yàn)閮?nèi)存不足而造成訪問速度下降的問題。
Redis提高數(shù)據(jù)庫容量的辦法有兩種:
1、一種是可以將數(shù)據(jù)分割到多個Redis Server上;
2、另一種是使用虛擬內(nèi)存把那些不經(jīng)常訪問的數(shù)據(jù)交換到磁盤上。
需要特別注意的是Redis并沒有使用OS提供的Swap,而是自己實(shí)現(xiàn)。
Redis為了保證查找的速度,只會將value交換出去,而在內(nèi)存中保留所有的Key。所以它非常適合Key很小,Value很大的存儲結(jié)構(gòu)。如果Key很大,value很小,那么vm可能還是無法滿足需求。
1、VM相關(guān)配置
通過在redis的redis.conf文件里,設(shè)置VM的相關(guān)參數(shù)來實(shí)現(xiàn)數(shù)據(jù)在內(nèi)存和磁盤之間 換入和 換出操作。
#開啟vm功能
vm-enabled yes
#交換出來的value保存的文件路徑
vm-swap-file /tmp/redis.swap
#設(shè)置當(dāng)內(nèi)存消耗達(dá)到上限時開始將value交換出來
vm-max-memory 1000000
#設(shè)置單個頁面的大小,單位是字節(jié)
vm-page-size 32
#設(shè)置最多能交換保存多少個頁到磁盤
vm-pages 13417728
#設(shè)置完成交換動作的工作線程數(shù),設(shè)置為0表示不使用工作線程而使用主線程,這會以阻塞的方式來運(yùn)行。建議設(shè)置成CPU核個數(shù)
vm-max-threads 4
在redis使用的內(nèi)存沒超過vm-max-memory時,是不會交換任何value到磁盤上的。當(dāng)超過最大內(nèi)存限制后,redis會選擇較老的對象(如果兩個對象一樣老會優(yōu)先交換比較大的對象)將它從內(nèi)存中移除,這樣會更加節(jié)約內(nèi)存。
對于Redis來說,一個數(shù)據(jù)頁面只會保存一個對象,也就是一個Value值,所以應(yīng)該將vm-page-size設(shè)置成大多數(shù)value可以保存進(jìn)去。如果設(shè)置太小,一個value對象就會占用幾個數(shù)據(jù)頁面,如果設(shè)置太大,就會造成頁面空閑空間浪費(fèi)。
2、VM的工作機(jī)制
redis的VM的工作機(jī)制分為兩種:一種是vm-max-threads=0,一種是vm-max-threads>0。
第一種:vm-max-threads = 0
主線程定期檢查使用的內(nèi)存大小,如果發(fā)現(xiàn)內(nèi)存超出最大上限,會直接以阻塞的方式,將選中的對象 換出 到磁盤上(保存到文件中),并釋放對象占用的內(nèi)存,此過程會一直重復(fù)直到下面條件滿足任意一條才結(jié)束:
1.內(nèi)存使用降到最大限制以下。
2.設(shè)置的交換文件數(shù)量達(dá)到上限。
3.幾乎全部的對象都被交換到磁盤了。
數(shù)據(jù)換入:
當(dāng)有client請求key對應(yīng)的value已被換出到磁盤中時,主線程會以阻塞的方式從換出文件中加載對應(yīng)的value對象,加載時此時會阻塞所有client,然后再處理client的請求。這種方式會阻塞所有的client。
第二種:vm-max-threads > 0
當(dāng)主線程檢測到使用內(nèi)存超過最大上限,會將選中的要交換的數(shù)據(jù)放到一個隊列中交由工作線程后臺處理,主線程會繼續(xù)處理client請求。
數(shù)據(jù)換入:
當(dāng)有client請求key的對應(yīng)的value已被換出到磁盤中時,主線程先阻塞當(dāng)前client,然后將加載對象的信息放到一個隊列中,讓工作線程去加載,此時進(jìn)主線程繼續(xù)處理其他client請求。加載完畢后工作線程通知主線程,主線程再執(zhí)行被阻塞的client的命令。這種方式只阻塞單個client。
總結(jié):Redis直接自己構(gòu)建了VM 機(jī)制 ,不會像一般的系統(tǒng)會調(diào)用系統(tǒng)函數(shù)處理,會浪費(fèi)一定的時間去 移動 和 請求,而Redis不存在。這也是Redis能夠那么快的一個原因。關(guān)注公眾號互聯(lián)網(wǎng)架構(gòu)師,在后臺回復(fù):2T,可以獲取我整理的 Redis 系列面試題和答案,非常齊全。
原文鏈接:https://blog.csdn.net/Seky_fei/article/details/106843764/
感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。
正文結(jié)束
1.不認(rèn)命,從10年流水線工人,到谷歌上班的程序媛,一位湖南妹子的勵志故事
3.從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧
5.37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...
6.IntelliJ IDEA 2019.3 首個最新訪問版本發(fā)布,新特性搶先看
一個人學(xué)習(xí)、工作很迷茫?
點(diǎn)擊「閱讀原文」加入我們的小圈子!

