Memcached工作原理
@[memcached]
[toc]
1. Memcached軟件工作原理
memcached是一套C/S模式架構(gòu)的軟件,在服務(wù)器端啟動(dòng)服務(wù)守護(hù)進(jìn)程,可以為memcached服務(wù)器指定監(jiān)聽(tīng)的IP地址、端口號(hào)、并發(fā)訪問(wèn)連接數(shù)、以及分配多少內(nèi)存來(lái)處理客戶端的請(qǐng)求的參數(shù);
memcached軟件是由C語(yǔ)言來(lái)實(shí)現(xiàn)的,全部代碼僅有2000多行,采用的是異步I/O,其實(shí)現(xiàn)方式是基于事件的單進(jìn)程和單線程的。使用libevent作為事件通知機(jī)制,多個(gè)服務(wù)器端可以協(xié)同工作,但這些服務(wù)器端之間是沒(méi)有任何通信聯(lián)系的,每個(gè)服務(wù)器只對(duì)自己的數(shù)據(jù)進(jìn)行管理。應(yīng)用程序端通過(guò)指定緩存服務(wù)器的IP地址和端口,就可以連接memcached服務(wù)進(jìn)行相互通信。
需要被緩存的數(shù)據(jù)以Key/Value鍵值對(duì)的形式保存在服務(wù)器端預(yù)分配的內(nèi)存空間中,每個(gè)被緩存的數(shù)據(jù)都有唯一的標(biāo)識(shí)Key,操作memcached中的數(shù)據(jù)是通過(guò)這個(gè)唯一標(biāo)識(shí)Key進(jìn)行的。緩存到Memcached中的數(shù)據(jù)僅放置在memcached服務(wù)預(yù)分配的內(nèi)存中,而非儲(chǔ)存在磁盤(pán)中,因此存取速度非???;
由于Memcached服務(wù)自身沒(méi)有對(duì)緩存的數(shù)據(jù)進(jìn)行持久性存儲(chǔ)的設(shè)計(jì),因此,在服務(wù)器端的memcached服務(wù)進(jìn)程重啟之后,存儲(chǔ)在內(nèi)存中的這些數(shù)據(jù)就會(huì)丟失。且當(dāng)內(nèi)存中緩存的數(shù)據(jù)容量達(dá)到啟動(dòng)時(shí)設(shè)定的內(nèi)存值時(shí),就自動(dòng)使用LRU(最近最少使用算法)算法刪除過(guò)期的緩存數(shù)據(jù)。
memcached軟件開(kāi)發(fā)的早,當(dāng)初僅為緩存而設(shè)計(jì)的,因此在設(shè)計(jì)之初并沒(méi)有過(guò)多考慮數(shù)據(jù)的永久性問(wèn)題。因此如果使用memcached作為緩存數(shù)據(jù)服務(wù),要考慮數(shù)據(jù)丟失后帶來(lái)的問(wèn)題,例如:是否可以重新生成數(shù)據(jù),還有,在高并發(fā)場(chǎng)合數(shù)據(jù)丟失會(huì)不會(huì)導(dǎo)致網(wǎng)站架構(gòu)雪崩。
為了滿足數(shù)據(jù)可以持久性保留的需求,sina網(wǎng)基于memcached服務(wù)開(kāi)發(fā)了一款NoSQL軟件,名字叫MemcacheDB,可以實(shí)現(xiàn)在緩存的基礎(chǔ)上增加了持久緩存的特性。
memcached支持各種語(yǔ)言編寫(xiě)的客戶端API,包括PHP 、PYthon、Java、C等;
2. memcached的特性
memcached作為高并發(fā)、高性能的緩存服務(wù),具有如下特征:
協(xié)議簡(jiǎn)單
memcached的協(xié)議實(shí)現(xiàn)比較簡(jiǎn)單,使用的是基于文本行的協(xié)議,能通過(guò)telnet直接操作memcached服務(wù)存取數(shù)據(jù);基于libevent的事件處理
簡(jiǎn)單的說(shuō),libevent是一套得C開(kāi)發(fā)的程序庫(kù),它將BSD系統(tǒng)的kqueue、Linux系統(tǒng)的epoll等事件處理功能封裝成一個(gè)接口,確保即使服務(wù)器端連接數(shù)增加,也能發(fā)揮很好的性能;
memcached就是利用這個(gè)庫(kù)進(jìn)行異步事件處理。內(nèi)置的內(nèi)存管理方式
memcached有一套自己管理內(nèi)存的方式,這套管理方式非常高效,所有的數(shù)據(jù)都保存在memcached內(nèi)置的內(nèi)存中,當(dāng)存入的數(shù)據(jù)占滿內(nèi)存空間時(shí),memcached就使用LRU算法自動(dòng)刪除不使用的緩存,即重用過(guò)期數(shù)據(jù)的內(nèi)存空間。memcached是為緩存系統(tǒng)設(shè)計(jì)的,因此,沒(méi)有考慮數(shù)據(jù)的容災(zāi)問(wèn)題,和機(jī)器的內(nèi)存一樣,重啟機(jī)器后數(shù)據(jù)將會(huì)丟失,如果希望重啟數(shù)據(jù)依然能保留,那么就需要采用sina網(wǎng)開(kāi)發(fā)的memcachedb持久性內(nèi)存緩存系統(tǒng),當(dāng)然還有常見(jiàn)的NoSQL服務(wù),如:Redis,內(nèi)存緩存:memcached,memcachedb,TokyoTyrant,MongoDB,Cassandra,redis,tair,CouchDB
linux運(yùn)維人員必會(huì)開(kāi)源運(yùn)維工具體系:http://oldboy.blog.51cto.com/2561410/775056互不通信的memcached服務(wù)之間具有分布式特征
各個(gè)memcached服務(wù)器之間互相不通信,都是獨(dú)立的存取數(shù)據(jù),不共享任何信息。通過(guò)對(duì)客戶端的設(shè)計(jì),讓Memcached具有分布式功能,能支持海量緩存和大規(guī)模應(yīng)用。
3. Memcached內(nèi)存管理機(jī)制
Memcached利用Slab Allocation機(jī)制來(lái)分配和管理內(nèi)存。傳統(tǒng)的內(nèi)存管理方式是:使用完通過(guò)malloc分配的內(nèi)存后通過(guò)free來(lái)回收內(nèi)存。這種方式容易產(chǎn)生內(nèi)存碎片并降低操作系統(tǒng)對(duì)內(nèi)存的管理效率。Slab Allocation機(jī)制不存在這樣的問(wèn)題。它按照預(yù)先分配的大小,將分配的內(nèi)存分割成特定長(zhǎng)度的內(nèi)存塊,再把尺寸相同的內(nèi)存塊分成組,這些內(nèi)存塊不會(huì)釋放,可以重復(fù)利用。
Memcached服務(wù)器端保存著一個(gè)空閑的內(nèi)存塊列表,當(dāng)有數(shù)據(jù)存入時(shí)根據(jù)接收到的數(shù)據(jù)大小,分配一個(gè)能存下這個(gè)數(shù)據(jù)的最小內(nèi)存塊。這種方式有時(shí)會(huì)造成內(nèi)存浪費(fèi),例如:將200字節(jié)的一個(gè)數(shù)據(jù)存入300字節(jié)的一個(gè)內(nèi)存塊中,就會(huì)有100字節(jié)的內(nèi)存被浪費(fèi)掉,不能被使用。
避免浪費(fèi)內(nèi)存的辦法是:
預(yù)先計(jì)算出應(yīng)用存入的數(shù)據(jù)大小,或把同一業(yè)務(wù)類型的數(shù)據(jù)存入一個(gè)Memcached服務(wù)器中,確保存入的數(shù)據(jù)大小相對(duì)均勻,這樣就可以減少內(nèi)存的浪費(fèi)。
還有一種辦法是,在memcached服務(wù)啟動(dòng)時(shí),通過(guò)“ -f ” 選項(xiàng)指定一個(gè)增長(zhǎng)因子(或叫增長(zhǎng)系數(shù)),它能控制內(nèi)存組(slab)之間的大小差異。在應(yīng)用中使用Memcached時(shí),通常可以不重新設(shè)置這個(gè)參數(shù),使用默認(rèn)值1.25進(jìn)行部署。如果想優(yōu)化memcached對(duì)內(nèi)存的使用,可以考慮重新計(jì)算數(shù)據(jù)的預(yù)期平均長(zhǎng)度,調(diào)整這個(gè)參數(shù)來(lái)獲得合適的設(shè)置值。
4. Memcached 的刪除機(jī)制
前面已經(jīng)介紹過(guò)Memcached不會(huì)釋放已分配的內(nèi)存空間,在數(shù)據(jù)過(guò)期后,客戶端不能通過(guò)Key取出它的值,其存儲(chǔ)空間被重新利用。
Memcached使用的是一種Lazy Expiration 策略,自己不會(huì)監(jiān)控存入的“Key/Value”對(duì)是否過(guò)期,而是在獲取Key值時(shí)查看記錄的時(shí)間戳,檢查“key/value”鍵值對(duì)的空間是否過(guò)期。這種策略不會(huì)在過(guò)期檢測(cè)上浪費(fèi)CPU資源。
Memcached在分配空間時(shí),優(yōu)先使用已經(jīng)過(guò)期的Key/Value鍵值對(duì)空間,當(dāng)分配的內(nèi)存空間占滿時(shí),Memcached就會(huì)使用LRU(最近最少使用算法)算法來(lái)分配空間,刪除最近最少使用的Key/Value鍵值對(duì),將其空間分配給新Key/Value鍵值對(duì)。在某些情況下,如果不想使用LRU算法,那么可以通過(guò)“-M” 參數(shù)來(lái)啟動(dòng)Memcached,這樣Memcached在內(nèi)存耗盡時(shí),會(huì)返回一個(gè)報(bào)錯(cuò)信息。