日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Memcache工作原理总结

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Memcache工作原理总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

<!--[if !supportLists]-->1.? <!--[endif]-->分片原理

?

咱們廢話話不多說了,直接看Memcache的原理。首先memcache解決的最大的一個問題就是內存多次讀取的內存碎片問題。內存碎片分為內存內部碎片和內存外部碎片。一般是指在外部碎片中出現了不連續的細小內存片段,不能夠被進程利用。因為不連續,不能組合成大而的連續空間,導致這部分空間很可惜的浪費了。內存碎片是因為在分配一個內存塊后,使之空閑,但不將空閑內存歸還給最大內存塊而產生的。

?

那么memcache啟動進程的時候就按照預先設定好的大小(默認是64mb)相內存開辟出一段連續的內存空間,之后再將這段內存空間分成不同的片段。

?

相信下面的圖大家都見過了

?



?

Memcache單進程最大可開的內存是2GB,如果想緩存更多的數據,建議還是開辟更多的memcache進程(不同端口)或者使用分布式memcache進行緩存,將數據緩存到不同的物理機或者虛擬機上。

?

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數組中選擇一個用于存儲數據。(http://blog.csdn.net/21aspnet/article/details/7022827)。在Page中才是一個個小存儲單元——chunks,一個page默認1mb,那么可以放多少個88字節單位的chunks呢?1024*1024/88約等于11915個。如果放入記錄是一個100字節的數據,那么在88字節的chunks和112字節的chunks中如何調配呢。答案當然是緊著大的用,不可能將請求過來的數據再做個分解、分離存儲、合并讀取吧。這樣也就帶來了一個小問題,還是有空間浪費掉了。112-100=12字節,這12字節就浪費了。

?

在緩存的清除方面,memcache是不釋放已分配內存。當已分配的內存所在的記錄失效后,這段以往的內存空間,memcache自然會重復利用起來。至于過期的方式,也是采取get到此段內存數據的時候采取查詢時間戳,看是否已經超時失效。基本不會有其他線程干預數據的生命周期。至于清空的策略等同于ehcache的默認策略——最近很少使用清空策略——也就是英文常用的LRU——Least Recently Used。

?

而memcache鑒定內存不足是在什么情況下呢:無法從slab里面獲取新的存儲單元了。這個對內存十分貪婪的東東。基本服務器都得是2~4GB以上方能吃得消(非時效性,或者說時效性較低的數據)。

?

Memcache借助了操作系統的libevent工具做高效的讀寫。libevent是個程序庫,它將Linux的epoll、BSD類操作系統的kqueue等事件處理功能封裝成統一的接口。即使對服務器的連接數增加,也能發揮高性能。memcached使用這個libevent庫,因此能在Linux、BSD、Solaris等操作系統上發揮其高性能。Memcache號稱可以接受任意數量的連接請求。事實真的是這樣嗎?

?

<!--[if !supportLists]-->1.? <!--[endif]-->存儲過程分析

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

Java代碼 ?
  • cachedClient?=?new?MemCachedClient();????
  • //獲取連接池實例????
  • SockIOPool?pool?=?SockIOPool.getInstance();????
  • ????
  • //設置緩存服務器地址,可以設置多個實現分布式緩存????
  • pool.setServers(new?String[]{"127.0.0.1:11211","192.176.17.90:11211"});??
  • ?那么在做存儲的時候memcache客戶端程序會hash出一個碼,之后再根據路由表去將請求轉發給memcache服務端,也就是說memcache的客戶端程序相當于做了一個類似負載均衡的功能。下面這個圖也是大家以前看過的

    ?



    ?

    ?

    而memcache在server上面的進程僅僅負責監聽服務和接受請求、存儲數據的作用。分發不歸他管。所以這么看的話,散列到每臺memcache服務機器,讓每臺機器分布存儲得均勻是客戶端代碼實現的一個難點。這個時侯Hash散列算法就顯得格外重要了吧。

    ?

    <!--[if !supportLists]-->1.? <!--[endif]-->讀取過程分析

    ?

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



    ?

    ?

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

    ?

    <!--[if !supportLists]-->1.? <!--[endif]-->與ehcache的爭論

    ?

    Ehcache的爭論之前就說過了,總是在性能上來說這兩個的性能如何。還有大家在網上常見的一個列表進行了比較。筆者覺得,這兩個最大的差異是原理的差異決定了應用場景的差異。比如做單點應用緩存的時候,就可以使用ehcache直接向本地內存進行緩存的讀寫。而做集群緩存的時候一般是借由一個集中式管理server來做緩存,既然是集中式server就少不了網絡傳輸了,這個時侯memcache較為適合。不是說ehcache不能做集群式的緩存,而是做了集群的緩存的代價(RMI、JMS、JGroups)、網絡資源的占用確實比memcache高一些。至于內存的讀寫操作效率,這個不太好說。Ehcache用java的隨機讀寫類操作二進制的buffer。Memcache底層是基于libevent程序庫的C服務。這個相信效率都差不多。關鍵的消耗還是在網絡IO資源上。

    總結

    以上是生活随笔為你收集整理的Memcache工作原理总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。