memcache記憶體分配機制

2021-09-08 17:10:38 字數 2707 閱讀 8318

memcached的記憶體分配沒有用到c語言中自帶的malloc函式,因為這個函式分配記憶體的時候效率很低,對於這種要求快速響應,對效率要求非常高的快取軟體來說非常不合適。

memcached用的是自己的一套記憶體分配方法,叫做slab allocation。

***64位的作業系統能分配 2gb 以上的記憶體。32位的作業系統中,每個程序最多只能使用 2gb 記憶體。

***如果想快取更多的資料,建議還是開闢更多的memcache程序(不同埠)或者使用分布式memcache進行快取,將資料快取到不同的物理機或者虛擬機器上。

***memcached啟動時指定的記憶體分配(如:-m 64)是memcached用於儲存資料的量,不包括memcached本身占用的記憶體、以及為了儲存資料而設定的管理空間。因此,memcached程序的實際記憶體分配量要比指定的容量要大。

memcache程序啟動,在記憶體開闢了連續的區域。咱們用上面的圖形來舉例,這段連續的區域就好像上面的slab1+slab2+slab3+……+slab(n).分配區域相同的構成了slab(分片組)。slab下面可不直接就是儲存區域片(就是圖中的chunks)了。而是page,如果乙個新的快取資料要被存放,memcached首先選擇乙個合適的slab,然後檢視該slab是否還有空閒的chunk,如果有則直接存放進去;如果沒有則要進行申請。

slab申請記憶體時以page為單位,所以在放入第乙個資料,無論大小為多少,都會有1m大小的page被分配給該slab。申請到page後,slab會將這個page的記憶體按chunk的大小進行切分,這樣就變成了乙個chunk的陣列,在從這個chunk陣列中選擇乙個用於儲存資料。在page中才是乙個個小儲存單元——chunks,乙個page預設1mb,那麼可以放多少個88位元組單位的chunks呢?1024*1024/88約等於11915個。如果放入記錄是乙個100位元組的資料,那麼在88位元組的chunks和112位元組的chunks中如何調配呢。答案當然是緊著大的用,不可能將請求過來的資料再做個分解、分離儲存、合併讀取吧。這樣也就帶來了乙個小問題,還是有空間浪費掉了。112-100=12位元組,這12位元組就浪費了。

memcache借助了作業系統的libevent工具做高效的讀寫。libevent是個程式庫,它將linux的epoll、bsd類作業系統的kqueue等事件處理功能封裝成統一的介面。即使對伺服器的連線數增加,也能發揮高效能。memcached使用這個libevent庫,因此能在linux、bsd、solaris等作業系統上發揮其高效能。memcache號稱可以接受任意數量的連線請求。事實真的是這樣嗎?

**乙個memcahced程序會預先將自己劃分為若干個slab,slab得數量是有限的,跟程序配置的記憶體無關,跟-f(增長因子),-i(page大小),-n(初始chunk大小)有關。

**slab的數量最大是200(當指定-f 1.0001)時,增長因子越大,slab越少,-f  不能小於1。

**可以通過-i指定page的大小,單位是byte,page預設是1m,最小需要1024byte, page值設定的越大slab越多。

**-n(最小分配空間):即初始chunk的大小,預設是48,此時初始chunk的大小是96,(注意並不是2倍的關係,當設定為50時,第乙個chunk的大小是104),-n越大slab越少。

**乙個slab可以申請多個page,當前slab下沒有資料時不會分配page。

推薦:對slab,page,chunk解釋的較詳細:

儲存過程分析

假設我們現在往memcache中儲存乙個快取記錄,首先在使用memcache客戶端程式的時候要制定乙個初始化的服務機器路由表,比如php的客戶端程式

$mc = new memcache();

$mc->addserver('192.168.1.110',11211);

$mc->addserver('192.168.1.120',11211);

$mc->addserver('192.168.1.130',11211);

那麼在做儲存的時候memcache客戶端程式會hash出乙個碼,之後再根據路由表去將請求**給memcache

服務端,也就是說memcache的客戶端程式相當於做了乙個類似負載均衡的功能。

而memcache在server上面的程序僅僅負責監聽服務和接受請求、儲存資料的作用。分發不歸他管。所以這麼看的話,雜湊到每台memcache服務機器,讓每台機器分布儲存得均勻是客戶端**實現的乙個難點。這個時侯hash雜湊演算法就顯得格外重要了吧。

讀取過程分析

理解了memcache的儲存就不難理解memcache的讀取快取的過程了。在讀取的時候也是根據key算出乙個hash,之後在算出指定的路由物理機位置,再將請求分發到服務機上。

memcache分布式讀寫的儲存方式有利有弊。如果node2宕機了,那麼node2的快取資料就沒了,那麼還得先從資料庫load出來資料,重新根據路由表(此時只有node1和node3),重新請求到乙個快取物理機上,在寫到重定向的快取機器中。災難恢復已經實現得較為完備。弊端就是維護這麼乙個高可用快取,成本有點兒大了。為了儲存更多的資料,這樣做是否利大於弊,還是得看具體的應用場景再定。

Memcache記憶體分配機制

1.page 頁 為記憶體分配的最小單位 memcached 的記憶體分配以page為單位,預設情況下乙個page是1m,可以通過 i引數在啟動時指定。如果需要申請記憶體時,memcached會劃分出乙個新的page並分配給需要的slab區域。page一旦被分配在重啟前不會被 或者重新分配 2.sl...

Memcache記憶體分配機制

memcached 的記憶體分配以page為單位,預設情況下乙個page是1m,可以通過 i引數在啟動時指定。如果需要申請記憶體時,memcached會劃分出乙個新的 page並分配給需要的slab區域。page一旦被分配在重啟前不會被 或者重新分配 memcached並不是將所有大小的資料都放在一...

C C 記憶體分配機制

1.c語言中的記憶體機制 在c語言中,記憶體主要分為如下5個儲存區 1 棧 stack 位於函式內的區域性變數 包括函式實參 由編譯器負責分配釋放,函式結束,棧變數失效。2 堆 heap 由程式設計師用malloc calloc realloc分配,free釋放。如果程式設計師忘記free了,則會造...