摘要:啟動時可以指定監聽的服務器的內網外網端口號所以做分布式測試時,一臺服務器上可以啟動多個不同端口號的進程使用的內存大小等關鍵參數。分布式實現原理的目前版本是通過實現,采用了單進程單線程異步,基于事件的服務方式使用作為事件通知實現。
1、什么是MemCache
官方說明:
MemCache是一個自由、源碼開放、高性能、分布式的分布式內存對象緩存系統,用于動態Web應用以減輕數據庫的負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高了網站訪問的速度。MemCaChe是一個存儲鍵值對的HashMap,在內存中對任意的數據(比如字符串、對象等)所使用的key-value存儲,數據可以來自數據庫調用、API調用,或者頁面渲染的結果。MemCache設計理念就是小而強大,它簡單的設計促進了快速部署、易于開發并解決面對大規模的數據緩存的許多難題,而所開放的API使得MemCache能用于Java、C/C++/C#、Perl、Python、PHP、Ruby等大部分流行的程序語言。
補充:
MemCache是一個高性能的分布式的內存對象緩存系統,用于各種動態應用以減輕數據庫負擔。它通過在內存中緩存數據和對象,來減少讀取數據庫的次數,從而提高動態、數據庫驅動應用速度。MemCache會在內存中開辟一塊空間,建立一個統一的巨大的hash表,hash表能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。
MemCache 和 MemCached:
MemCache是這個項目的名稱,而MemCached是服務器端的主程序名稱。
2、MemCached使用場景通常,我們會在訪問量高的Web網站和應用中使用MemCache,用來緩解數據庫的壓力,并且提升網站和應用的響應速度。
在應用程序中,我們通常在以下節點來使用MemCached:
訪問頻繁的數據庫數據(身份token、首頁動態)
訪問頻繁的查詢條件和結果
作為Session的存儲方式(提升Session存取性能)
頁面緩存
更新頻繁的非重要數據(訪客量、點擊次數)
大量的hot數據
常用工作流程(如下圖):
客戶端請求數據
檢查MemCached中是否有對應數據
有的話直接返回,結束
沒有的話,去數據庫里請求數據
將數據寫入MemCached,供下次請求時使用
返回數據,結束
(注意:緩存到MemCached中的數據庫數據,在更新數據庫時要注意同時更新MemCached)
3、MemCached工作原理MemCached采用了C/S架構,在Server端啟動后,以守護程序的方式,監聽客戶端的請求。啟動時可以指定監聽的IP(服務器的內網ip/外網ip)、端口號(所以做分布式測試時,一臺服務器上可以啟動多個不同端口號的MemCached進程)、使用的內存大小等關鍵參數。一旦啟動,服務就會一直處于可用狀態。
為了提高性能,MemCached緩存的數據全部存儲在MemCached管理的內存中,所以重啟服務器之后緩存數據會清空,不支持持久化。
slab_class里,存放的是一組組chunk大小相同的slab
每個slab里面包含若干個page,page的默認大小是1M,如果slab大小100M,就包含100個page
每個page里面包含若干個chunk,chunk是數據的實際存放單位,每個slab里面的chunk大小相同
內存分配方式Memcached利用slab allocation機制來分配和管理內存,它按照預先規定的大小,將分配的內存分割成特定長度的內存塊,再把尺寸相同的內存塊分成組,數據在存放時,根據鍵值大小去匹配slab大小,找就近的slab存放,所以存在空間浪費現象。而傳統的內存管理方式是,使用完通過malloc分配的內存后通過free來回收內存,這種方式容易產生內存碎片并降低操作系統對內存的管理效率。
存放數據時,首先slab要申請內存,申請內存是以page為單位的。所以在放入第一個數據的時候,無論大小為多少,都會有1M大小的page被分配給該slab。申請到page后,slab會將這個page的內存按chunk的大小進行切分,這樣就變成了一個chunk數組,最后從這個chunk數組中選擇一個用于存儲數據。
示例:
MemCache中的value存放位置是由value的大小決定,value會被存放到與chunk大小最接近的一個slab中,比如slab[1]的chunk大小為88字節、slab[2]的chunk大小為112字節、slab[3]的chunk大小為144字節(默認相鄰slab內的chunk基本以1.25為比例進行增長,MemCache啟動時可以用-f指定這個比例),那么一個100字節的value,將被放到2號slab中。
內存回收方式當數據容量用完MemCached分配的內存后,就會基于LRU(Least Recently
Used)算法清理失效的緩存數據(放入數據時可設置失效時間),或者清理最近最少使用的緩存數據,然后放入新的數據。
在LRU中,MemCached使用的是一種Lazy
Expiration策略,自己不會監控存入的key/vlue對是否過期,而是在獲取key值時查看記錄的時間戳,檢查key/value對空間是否過期,這樣可減輕服務器的負載。
需要注意的是,如果如果MemCache啟動沒有追加-M,則表示禁止LRU,這種情況下內存不夠會報Out Of Memory錯誤。
針對MemCache的內存分配及回收算法,總結三點:
MemCache的內存分配chunk里面會有內存浪費,88字節的value分配在128字節(緊接著大的用)的chunk中,就損失了30字節,但是這也避免了管理內存碎片的問題
MemCache的LRU算法不是針對全局的,是針對slab的
應該可以理解為什么MemCache存放的value大小是限制的,因為一個新數據過來,slab會先以page為單位申請一塊內存,申請的內存最多就只有1M,所以value大小自然不能大于1M了
(2)MemCached分布式為了提升MemCached的存儲容量和性能,我們應用的客戶端可能會對應多個MemCached服務器來提供服務,這就是MemCached的分布式。分布式實現原理
MemCached的目前版本是通過C實現,采用了單進程、單線程、異步I/O,基于事件(event_based)的服務方式.使用libevent作為事件通知實現。多個Server可以協同工作,但這些 Server 之間保存的數據各不相同,而且并不通信(與之形成對比的,比如JBoss Cache,某臺服務器有緩存數據更新時,會通知集群中其他機器更新緩存或清除緩存數據),每個Server只是對自己的數據進行管理。
Client端通過IP地址和端口號指定Server端,將需要緩存的數據是以key->value對的形式保存在Server端。key的值通過hash進行轉換,根據hash值把value傳遞到對應的具體的某個Server上。當需要獲取對象數據時,也根據key進行。首先對key進行hash,通過獲得的值可以確定它被保存在了哪臺Server上,然后再向該Server發出請求。Client端只需要知道保存hash(key)的值在哪臺服務器上就可以了。
當向MemCached集群存入/取出key/value時,MemCached客戶端程序根據一定的算法計算存入哪臺服務器,然后再把key/value值存到此服務器中。也就是說,存取數據分二步走,第一步,選擇服務器,第二步存取數據。
分布式算法解析余數算法:
先求得鍵的整數散列值(也是就鍵string的HashCODE值 什么是HashCode),再除以服務器臺數,根據余數確定存取服務器,這種方法計算簡單,高效,但在memcached服務器增加或減少時,幾乎所有的緩存都會失效。
散列算法:
先算出MemCached服務器的散列值,并將其分布到0到2的32次方的圓上,然后用同樣的方法算出存儲數據的鍵的散列值并映射至圓上,最后從數據映射到的位置開始順時針查找,將數據保存到查找到的第一個服務器上,如果超過2的32次方,依然找不到服務器,就將數據保存到第一臺MemCached服務器上。如果添加了一臺MemCached服務器,只在圓上增加服務器的逆時針方向的第一臺服務器上的鍵會受到影響。
MemCached網絡模型是典型的單進程多線程模型,采用libevent處理網絡請求,主進程負責將新來的連接分配給work線程,work線程負責處理連接,有點類似與負載均衡,通過主進程分發到對應的工作線程。
MemCached默認有7個線程,4個主要的工作線程,3個輔助線程,線程可劃分為以下4種:
主線程,負責MemCached服務器初始化,監聽TCP、Unix Domain連接請求;
工作線程池,MemCached默認4個工作線程,可通過啟動參數修改,負責處理TCP、UDP,Unix域套接口鏈路上的請求;
assoc維護線程,MemCached內存中維護一張巨大的hash表,該線程負責hash表動態增長;
slab維護線程,即內存管理模塊維護線程,負責class中slab的平衡,MemCached啟動選項中可關閉該線程。
更多見:MemCache-網絡線程模型-原碼分析
4、MemCached特性與限制MemCache中可以保存的item數據量是沒有限制的,只要內存足夠
MemCache單進程在32位機中最大使用內存為2G,這個之前的文章提了多次了,64位機則沒有限制
Key最大為250個字節,超過該長度無法存儲
單個item最大數據是1MB,超過1MB的數據不予存儲
MemCache服務端是不安全的,比如已知某個MemCache節點,可以直接telnet過去,并通過flush_all讓已經存在的鍵值對立即失效,所以MemCache服務器最好配置到內網環境,通過防火墻制定可訪問客戶端
不能夠遍歷MemCache中所有的item,因為這個操作的速度相對緩慢且會阻塞其他的操作
MemCached的高性能源自于兩階段哈希結構:第一階段在客戶端,通過Hash算法根據Key值算出一個節點;第二階段在服務端,通過一個內部的Hash算法,查找真正的item并返回給客戶端。從實現的角度看,MemCache是一個非阻塞的、基于事件的服務器程序
MemCache設置添加某一個Key值的時候,傳入expiry為0表示這個Key值永久有效,這個Key值也會在30天之后失效,見memcache.c的源代碼:
#define REALTIME_MAXDELTA 60*60*24*30 static rel_time_t realtime(const time_t exptime) { if (exptime == 0) return 0; if (exptime > REALTIME_MAXDELTA) { if (exptime <= process_started) return (rel_time_t)1; return (rel_time_t)(exptime - process_started); } else { return (rel_time_t)(exptime + current_time); } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/28133.html
摘要:啟動時可以指定監聽的服務器的內網外網端口號所以做分布式測試時,一臺服務器上可以啟動多個不同端口號的進程使用的內存大小等關鍵參數。分布式實現原理的目前版本是通過實現,采用了單進程單線程異步,基于事件的服務方式使用作為事件通知實現。 1、什么是MemCache 官方說明: MemCache是一個自由、源碼開放、高性能、分布式的分布式內存對象緩存系統,用于動態Web應用以減輕數據庫的負載。它...
摘要:繼周一發布的面試常考內容之和后,這是第二篇,感謝你的支持和閱讀。預告面試常考內容之和將于本周五更新。以上內容摘自程序員面試筆試寶典書籍,該書已在天貓京東當當等電商平臺銷售。 你好,是我琉憶。繼周一(2019.2-18)發布的PHP面試常考內容之Memcache和Redis(1)后,這是第二篇,感謝你的支持和閱讀。本周(2019.2-18至2-22)的文章內容點為以下幾點,更新時間為每周...
摘要:繼周一發布的面試常考內容之和后,這是第二篇,感謝你的支持和閱讀。預告面試常考內容之和將于本周五更新。以上內容摘自程序員面試筆試寶典書籍,該書已在天貓京東當當等電商平臺銷售。 你好,是我琉憶。繼周一(2019.2-18)發布的PHP面試常考內容之Memcache和Redis(1)后,這是第二篇,感謝你的支持和閱讀。本周(2019.2-18至2-22)的文章內容點為以下幾點,更新時間為每周...
摘要:接下來將介紹分布式緩存的典型代表,以及分布式緩存的應用場景。的分布式實現本身并不是一種分布式的緩存系統,它的分布式是由訪問它的客戶端來實現的。 前言:本書是對分布式系統架構涉及到的相關技術的一本科普書籍。由于很難作為開發參考,只能但求了解。所以通篇淺讀,對分布式系統進行大致的了解。因為寫的非常好,感覺非常有意思,自己也做不出總結。所謂的讀書筆記也就演變成了摘抄。 簡介 一個大型、穩健、...
閱讀 2451·2021-10-13 09:40
閱讀 3337·2019-08-30 13:46
閱讀 1125·2019-08-29 14:05
閱讀 2961·2019-08-29 12:48
閱讀 3657·2019-08-26 13:28
閱讀 2148·2019-08-26 11:34
閱讀 2284·2019-08-23 18:11
閱讀 1163·2019-08-23 12:26