Redis VM使用

Redis VM使用

Redis處理的速度很快,因?yàn)樗腔趦?nèi)存的。在內(nèi)存能夠足夠容納數(shù)據(jù)的時(shí)候,所有的數(shù)據(jù)都存放在內(nèi)存。這個(gè)時(shí)候不論是讀取數(shù)據(jù)還是寫(xiě)入數(shù)據(jù)都是非??斓?。但是如果數(shù)據(jù)量很大,大到內(nèi)存已經(jīng)無(wú)法全部容納的時(shí)候,我想對(duì)存儲(chǔ)有一定了解的人都在想,這個(gè)時(shí)候redis是怎么處理的呢?處理速度是否會(huì)直線下降?

幸虧,答案是否定的。Redis使用到了VM,在redis.conf設(shè)置vm-enabled yes 即開(kāi)啟VM功能。 通過(guò)VM功能可以實(shí)現(xiàn)冷熱數(shù)據(jù)分離。使熱數(shù)據(jù)仍在內(nèi)存中,冷數(shù)據(jù)保存到磁盤(pán)。這樣就可以避免因?yàn)閮?nèi)存不足而造成訪問(wèn)速度下降的問(wèn)題。在這里,需要特別提到的是,Redis并沒(méi)有使用OS提供的Swap,而是自己實(shí)現(xiàn)。作者在自己的blog說(shuō)明了原因:

1:OS是基于page(4K)來(lái)做的,它的粒度對(duì)于Redis來(lái)說(shuō)太大。而redis的大多數(shù)對(duì)象都遠(yuǎn)小于4k,所以一個(gè)OS頁(yè)面上可能有多個(gè)redis對(duì)象。另外redis的集合對(duì)象類(lèi)型如list,set可能存在與多個(gè)OS頁(yè)面上。最終可能造成只有10%的key被經(jīng)常訪問(wèn),但是所有OS頁(yè)面都會(huì)被OS認(rèn)為是活躍的,這樣只有內(nèi)存真正耗盡時(shí)OS才會(huì)交換頁(yè)面。

2:相比于OS的交換方式。redis可以將被交換到磁盤(pán)的對(duì)象進(jìn)行壓縮,保存到磁盤(pán)的對(duì)象可以去除指針和對(duì)象元數(shù)據(jù)信息。一般壓縮后對(duì)象會(huì)比內(nèi)存中對(duì)象小10倍。這樣redis的vm會(huì)比OS vm能少做很多io操作。

3:OS交換的時(shí)候,是會(huì)阻塞線程的,而Redis可以設(shè)置讓工作線程來(lái)完成,主線程仍可以繼續(xù)接收client的請(qǐng)求。

開(kāi)啟VM功能后,還有其他幾個(gè)設(shè)置需要設(shè)置vm-swap-file:設(shè)置被交換出的值保存到磁盤(pán)的位置。vm-max-memory:設(shè)置當(dāng)內(nèi)存消耗達(dá)到上限時(shí)開(kāi)始將value交換出來(lái)。vm-page-size:設(shè)置單個(gè)頁(yè)面的大小,單位是字節(jié)。vm-pages:設(shè)置最多能交換保存多少個(gè)頁(yè)到磁盤(pán)??梢运愠隹梢越粨Q出來(lái)的最大大小為vm-page-size * vm-pages。vm-max-threads:設(shè)置完成交換動(dòng)作的工作線程數(shù),設(shè)置為0表示不使用工作線程而使用主線程,這會(huì)以阻塞的方式來(lái)運(yùn)行。建議設(shè)置成CPU核個(gè)數(shù)。

Redis為了保證查找的速度,只會(huì)將value交換出去,而在內(nèi)存中保留所有的Key。所以它非常適合Key很小,Value很大的存儲(chǔ)結(jié)構(gòu)。如果Key很大,value很小,那么vm可能還是無(wú)法滿足需求。redis規(guī)定同一個(gè)頁(yè)面只能保存一個(gè)對(duì)象。但是一個(gè)對(duì)象可以保存在多個(gè)頁(yè)面中。在redis使用的內(nèi)存沒(méi)超過(guò)vm-max-memory之前是不會(huì)交換任何value的。當(dāng)超過(guò)最大內(nèi)存限制后,redis會(huì)選擇較老的對(duì)象。如果兩個(gè)對(duì)象一樣老會(huì)優(yōu)先交換比較大的對(duì)象,將它從內(nèi)存中移除,這樣會(huì)更加節(jié)約內(nèi)存。精確的公式swappability = age*log(size_in_memory)。

既然對(duì)于Redis來(lái)說(shuō),一個(gè)頁(yè)面只會(huì)保存一個(gè)對(duì)象,也就是一個(gè)Value值,所以應(yīng)該將vm-page-size設(shè)置成大多數(shù)value可以保存進(jìn)去。如果設(shè)置太小,一個(gè)value對(duì)象就會(huì)占用幾個(gè)頁(yè)面,如果設(shè)置太大,就會(huì)造成頁(yè)面空閑空間浪費(fèi)。每個(gè)頁(yè)面,Redis都會(huì)在內(nèi)存中使用1比特(bit)長(zhǎng)度來(lái)保存頁(yè)面的空閑狀態(tài)。如果設(shè)置的vm-pages非常大,那么光用來(lái)保存頁(yè)面狀態(tài)就會(huì)花費(fèi)很大的內(nèi)存。

VM的工作機(jī)制:分為兩種

第一種:vm-max-threads = 0

換出

主線程定期檢查使用的內(nèi)存大小,如果發(fā)現(xiàn)內(nèi)存超出最大上限,會(huì)直接以阻塞的方式,將選中的對(duì)象保存到換出文件中,并釋放對(duì)象占用的內(nèi)存,此過(guò)程會(huì)一直重復(fù)直到下面條件滿足:
  1.內(nèi)存使用降到最大限制以下,2. 設(shè)置的交換文件數(shù)量達(dá)到上限,3. 幾乎全部的對(duì)象都被交換到磁盤(pán)了

換入

當(dāng)有client請(qǐng)求的value之前已被換出時(shí),主線程會(huì)以阻塞的方式從換出文件中加載對(duì)應(yīng)的value對(duì)象,加載時(shí)此時(shí)會(huì)阻塞所有client,然后再處理client的請(qǐng)求。

第二種:vm-max-threads > 0

換出

當(dāng)主線程檢測(cè)到使用內(nèi)存超過(guò)最大上限,會(huì)將選中的要交換的對(duì)象信息放到一個(gè)隊(duì)列中交由工作線程后臺(tái)處理,主線程會(huì)繼續(xù)處理client請(qǐng)求。
   換入

如果有client請(qǐng)求value之前已被換出時(shí),主線程先阻塞當(dāng)個(gè)client,然后將加載對(duì)象的信息放到一個(gè)隊(duì)列中,讓工作線程去加載,此進(jìn)主線程繼續(xù)處理其他client請(qǐng)求。加載完畢后工作線程通知主線程。主線程再執(zhí)行被阻塞的client的命令。這種方式只阻塞單個(gè)client。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 摘自http://xiaoh.me/2016/06/30/redis-advanced/ 排序 redis支持對(duì)l...
    鴕鳥(niǎo)要抬頭閱讀 66,823評(píng)論 1 3
  • 安全性 設(shè)置客戶端連接后進(jìn)行任何其他指令前需要使用的密碼。 警告:因?yàn)閞edis 速度相當(dāng)快,所以在一臺(tái)比較好的服...
    OzanShareing閱讀 1,948評(píng)論 1 7
  • Redis是一個(gè)支持持久化的內(nèi)存數(shù)據(jù)庫(kù),也就是說(shuō)redis需要經(jīng)常將內(nèi)存中的數(shù)據(jù)同步到磁盤(pán)來(lái)保證持久化。redis...
    孫培培棒棒噠閱讀 609評(píng)論 0 1
  • redis高級(jí)用法包括:排序事務(wù)管道發(fā)布/訂閱持久化主從復(fù)制虛擬內(nèi)存 排序可以對(duì)list和set和zset進(jìn)行排序...
    舒小賤閱讀 499評(píng)論 0 2
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,674評(píng)論 1 32

友情鏈接更多精彩內(nèi)容