天天看點

Memcached與Redis(三)

3. Memcached和Redis關鍵技術對比

作為記憶體資料緩沖系統,Memcached和Redis均具有很高的性能,但是兩者在關鍵實作技術上具有很大差異,這種差異決定了兩者具有不同的特點和不同的适用條件。下面我們會對兩者的關鍵技術進行一些對比,以此來揭示兩者的差異。

3.1 Memcached和Redis的記憶體管理機制對比

對于像Redis和Memcached這種基于記憶體的資料庫系統來說,記憶體管理的效率高低是影響系統性能的關鍵因素。傳統C語言中的malloc/free函數是最常用的配置設定和釋放記憶體的方法,但是這種方法存在着很大的缺陷:首先,對于開發人員來說不比對的malloc和free容易造成記憶體洩露;其次,頻繁調用會造成大量記憶體碎片無法回收重新利用,降低記憶體使用率;最後,作為系統調用,其系統開銷遠遠大于一般函數調用。是以,為了提高記憶體的管理效率,高效的記憶體管理方案都不會直接使用malloc/free調用。Redis和Memcached均使用了自身設計的記憶體管理機制,但是實作方法存在很大的差異,下面将會對兩者的記憶體管理機制分别進行介紹。

3.1.1 Memcached的記憶體管理機制

Memcached預設使用Slab Allocation機制管理記憶體,其主要思想是按照預先規定的大小,将配置設定的記憶體分割成特定長度的塊以存儲相應長度的key-value資料記錄,以完全解決記憶體碎片問題。Slab Allocation機制隻為存儲外部資料而設計,也就是說所有的key-value資料都存儲在Slab Allocation系統裡,而Memcached的其它記憶體請求則通過普通的malloc/free來申請,因為這些請求的數量和頻率決定了它們不會對整個系統的性能造成影響

Slab Allocation的原理相當簡單。 如圖3所示,它首先從作業系統申請一大塊記憶體,并将其分割成各種尺寸的塊Chunk,并把尺寸相同的塊分成組Slab Class。其中,Chunk就是用來存儲key-value資料的最小機關。每個Slab Class的大小,可以在Memcached啟動的時候通過制定Growth Factor來控制。假定Figure 1中Growth Factor的取值為1.25,是以如果第一組Chunk的大小為88個位元組,第二組Chunk的大小就為112個位元組,依此類推。

Memcached與Redis(三)

圖3 Memcached記憶體管理架構

當Memcached接收到用戶端發送過來的資料時首先會根據收到資料的大小選擇一個最合适的Slab Class,然後通過查詢Memcached儲存着的該Slab Class内空閑Chunk的清單就可以找到一個可用于存儲資料的Chunk。當一條資料庫過期或者丢棄時,該記錄所占用的Chunk就可以回收,重新添加到空閑清單中。從以上過程我們可以看出Memcached的記憶體管理制效率高,而且不會造成記憶體碎片,但是它最大的缺點就是會導緻空間浪費。因為每個Chunk都配置設定了特定長度的記憶體空間,是以變長資料無法充分利用這些空間。如圖 4所示,将100個位元組的資料緩存到128個位元組的Chunk中,剩餘的28個位元組就浪費掉了。

Memcached與Redis(三)

圖4 Memcached的存儲空間浪費

3.1.2 Redis的記憶體管理機制

Redis的記憶體管理主要通過源碼中zmalloc.h和zmalloc.c兩個檔案來實作的。Redis為了友善記憶體的管理,在配置設定一塊記憶體之後,會将這塊記憶體的大小存入記憶體塊的頭部。如圖 5所示,real_ptr是redis調用malloc後傳回的指針。redis将記憶體塊的大小size存入頭部,size所占據的記憶體大小是已知的,為size_t類型的長度,然後傳回ret_ptr。當需要釋放記憶體的時候,ret_ptr被傳給記憶體管理程式。通過ret_ptr,程式可以很容易的算出real_ptr的值,然後将real_ptr傳給free釋放記憶體。

Memcached與Redis(三)

圖5 Redis塊配置設定

Redis通過定義一個數組來記錄所有的記憶體配置設定情況,這個數組的長度為ZMALLOC_MAX_ALLOC_STAT。數組的每一個元素代表目前程式所配置設定的記憶體塊的個數,且記憶體塊的大小為該元素的下标。在源碼中,這個數組為zmalloc_allocations。zmalloc_allocations[16]代表已經配置設定的長度為16bytes的記憶體塊的個數。zmalloc.c中有一個靜态變量used_memory用來記錄目前配置設定的記憶體總大小。是以,總的來看,Redis采用的是包裝的mallc/free,相較于Memcached的記憶體管理方法來說,要簡單很多。

本文轉自liujing0751CTO部落格,原文連結:http://blog.51cto.com/13281352/1981038 ,如需轉載請自行聯系原作者

繼續閱讀