memcache雜談

<

成都創(chuàng)新互聯(lián)專注于呼蘭網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供呼蘭營銷型網(wǎng)站建設(shè),呼蘭網(wǎng)站制作、呼蘭網(wǎng)頁設(shè)計、呼蘭網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造呼蘭網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供呼蘭網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。div>基本問題

1、memcached的基本設(shè)置
1)啟動Memcache的服務(wù)器端
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid


-d選項是啟動一個守護進程,
-m是分配給Memcache使用的內(nèi)存數(shù)量,單位是MB,我這里是10MB,
-u是運行Memcache的用戶,我這里是root,
-l是監(jiān)聽的服務(wù)器IP地址,如果有多個地址的話,我這里指定了服務(wù)器的IP地址192.168.0.200,
-p是設(shè)置Memcache監(jiān)聽的端口,我這里設(shè)置了12000,最好是1024以上的端口,
-c選項是運行的并發(fā)連接數(shù),默認是1024,我這里設(shè)置了256,按照你服務(wù)器的負載量來設(shè)定,
-P是設(shè)置保存Memcache的pid文件,我這里是保存在 /tmp/memcached.pid,

2)如果要結(jié)束Memcache進程,執(zhí)行:

# kill `cat /tmp/memcached.pid`

哈希算法將任意長度的二進制值映射為固定長度的較小二進制值,這個小的二進制值稱為哈希值。哈希值是一段數(shù)據(jù)唯一且極其緊湊的數(shù)值表示形式。如果散列一段明文而且哪怕只更改該 段落的一個字母,隨后的哈希都將產(chǎn)生不同的值。要找到散列為同一個值的兩個不同的輸入,在計算上是不可能的。

2、一致性Hash算法的目的有兩點:一是節(jié)點變動后其他節(jié)點受影響盡可能?。欢枪?jié)點變動后數(shù)據(jù)重新分配盡可能均衡 。

3、為什么要運行 memcached ?

如果網(wǎng)站的高流量很大并且大多數(shù)的訪問會造成數(shù)據(jù)庫高負荷的狀況下,使用 memcached 能夠減輕數(shù)據(jù)庫的壓力。

4、適用memcached的業(yè)務(wù)場景?

1)如果網(wǎng)站包含了訪問量很大的動態(tài)網(wǎng)頁,因而數(shù)據(jù)庫的負載將會很高。由于大部分數(shù)據(jù)庫請求都是讀操作,那么memcached可以顯著地減小數(shù)據(jù)庫負載。

2)如果數(shù)據(jù)庫服務(wù)器的負載比較低但CPU使用率很高,這時可以緩存計算好的結(jié)果( computed objects )和渲染后的網(wǎng)頁模板(enderred templates)。

3)利用memcached可以緩存session數(shù)據(jù)、臨時數(shù)據(jù)以減少對他們的數(shù)據(jù)庫寫操作。

4)緩存一些很小但是被頻繁訪問的文件。

5)緩存Web \'services\'(非IBM宣揚的Web Services,譯者注)或RSS feeds的結(jié)果.。

5、不適用memcached的業(yè)務(wù)場景?

1)緩存對象的大小大于1MB

Memcached本身就不是為了處理龐大的多媒體(large media)和巨大的二進制塊(streaming huge blobs)而設(shè)計的。

2)key的長度大于250字符

3)虛擬主機不讓運行memcached服務(wù)

如果應(yīng)用本身托管在低端的虛擬私有服務(wù)器上,像vmware, xen這類虛擬化技術(shù)并不適合運行memcached。Memcached需要接管和控制大塊的內(nèi)存,如果memcached管理的內(nèi)存 被OS或 hypervisor交換出去,memcached的性能將大打折扣。

4)應(yīng)用運行在不安全的環(huán)境中

Memcached為提供任何安全策略,僅僅通過telnet就可以訪問到memcached。如果應(yīng)用運行在共享的系統(tǒng)上,需要著重考慮安全問題。

5)業(yè)務(wù)本身需要的是持久化數(shù)據(jù)或者說需要的應(yīng)該是database

6、能夠遍歷memcached中所有的item嗎?

不能,這個操作的速度相對緩慢且阻塞其他的操作(這里的緩慢時相比memcached其他的命令)。memcached所有非調(diào)試(non-debug)命令,例如add, set, get, fulsh等無論 memcached中存儲了多少數(shù)據(jù),它們的執(zhí)行都只消耗常量時間。任何遍歷所有item的命令執(zhí)行所消耗的時間,將隨著memcached中數(shù)據(jù)量的增加而增加。當其他命令因為等待(遍歷所
有item的命令執(zhí)行完畢)而不能得到執(zhí)行,因而阻塞將發(fā)生。

集群的相關(guān)問題

7、memcached是怎么工作的?

Memcached的高性能源于兩階段哈希(two-stage hash)結(jié)構(gòu)。Memcached就像一個巨大的、存儲了很多<key,value>對的哈希表。通過key,可以存儲或查詢?nèi)我獾臄?shù)據(jù)。 客戶端

可以把數(shù)據(jù)存儲在多臺memcached上。當查詢數(shù)據(jù)時,客戶端首先參考節(jié)點列表計算出key的哈希值(階段一哈希),進而選中一個節(jié)點;客戶端將請求發(fā)送給選中的節(jié)點,然后 memcached節(jié)點通過一個內(nèi)部的哈希算法(階段二哈希),查找真正的數(shù)據(jù)(item)并返回給客戶端。從實現(xiàn)的角度看,memcached是一個非阻塞的、基于事件的服務(wù)器程序。

8、memcached的優(yōu)勢是什么?

Memcached的好處就是它帶來了極佳的水平可擴展性,特別是在一個巨大的系統(tǒng)中。由于客戶端自己做了一次哈希,那么我們很容易增加大量memcached到集群中。memcached 之間沒有相互通信,因此不會增加 memcached的負載;沒有多播協(xié)議,不會網(wǎng)絡(luò)通信量爆炸(implode)。

9、memcached和MySQL的query cache相比,有什么優(yōu)缺點?

缺點:

1)相比MySQL的query cache,把memcached引入應(yīng)用中需要不少的工作量。MySQL的query cache,可以自動地緩存SQL查詢的結(jié)果,被緩存的SQL查詢可以被反復(fù)、快速的執(zhí)行。

優(yōu)點:

1)當修改表時,MySQL的query cache會立刻被刷新(flush)。當寫操作很頻繁時,MySQL的query cache會經(jīng)常讓所有緩存數(shù)據(jù)都失效。

2)在多核CPU上,MySQL的query cache會遇到擴展問題(scalability issues)。在多核CPU上,query cache會增加一個全局鎖(global lock), 由于需要刷新更多的緩存數(shù)據(jù),速度 會變得更慢。

3)在MySQL的query cache中,是不能存儲任意的數(shù)據(jù)的(只能是SQL查詢結(jié)果)。利用memcached,我們可以搭建出各種高效的緩存。比如,可以執(zhí)行多個獨立的查詢,構(gòu)建出一個

用戶對象(user object),然后將用戶對象緩存到memcached中。而query cache是SQL語句級別的,不可能做到這一點。在小的網(wǎng)站中,query cache會有所幫助,但隨著網(wǎng)站規(guī)模的 增加,query cache的弊將大于利。

4)query cache能夠利用的內(nèi)存容量受到MySQL服務(wù)器空閑內(nèi)存空間的限制。給數(shù)據(jù)庫服務(wù)器增加更多的內(nèi)存來緩存數(shù)據(jù),固然是很好的。但是,有了memcached,只要您有空閑的內(nèi) 存,都可以用來增加memcached集群的規(guī)模,然后您就可以緩存更多的數(shù)據(jù)。

10、memcached和服務(wù)器的local cache(比如PHP的APC、mmap文件等)相比,有什么優(yōu)缺點?

1)首先,local cache面臨著嚴重的內(nèi)存限制,能夠利用的內(nèi)存容量受到(單臺)服務(wù)器空閑內(nèi)存空間的限制。

2)local cache有一點比memcached和query cache都要好,那就是它不但可以存儲任意的數(shù)據(jù),而且沒有網(wǎng)絡(luò)存取的延遲。因此,local cache的數(shù)據(jù)查詢更快。考慮把highly common的數(shù)據(jù)放在local cache中吧。如果每個頁面都需要加載一些數(shù)量較少的數(shù)據(jù),可以考慮把它們放在local cached。

3)local cache缺少集體失效(group invalidation)的特性。在memcached集群中,刪除或更新一個key會讓所有的觀察者覺察到。但是在local cache中, 我們只能通知所有的服務(wù)器 刷新cache(很慢,不具擴展性)或者僅僅依賴緩存超時失效機制。

11、memcached的cache機制是怎樣的?

Memcached主要的cache機制是LRU(最近最少用)算法+超時失效。當您存數(shù)據(jù)到memcached中,可以指定該數(shù)據(jù)在緩存中可以呆多久Which is forever, or some time in the future。如果memcached的內(nèi)存不夠用了,過期的slabs會優(yōu)先被替換,接著就輪到最老的未被使用的slabs。

12、memcached如何實現(xiàn)冗余機制?

不實現(xiàn)!Memcached應(yīng)該是應(yīng)用的緩存層,從設(shè)計本身來京就不帶有任何冗余機制。如果一個memcached節(jié)點失去了所有數(shù)據(jù),應(yīng)該可以從數(shù)據(jù)源(比如數(shù)據(jù)庫)再次獲取到數(shù)據(jù)。應(yīng) 用系統(tǒng)應(yīng)該可以容忍節(jié)點的失效。如果擔心節(jié)點失效會大大加重數(shù)據(jù)庫的負擔,那么可以采取一些辦法。比如您可以增加更多的節(jié)點(來減少丟失一個節(jié)點的影響),熱備節(jié)點(在其他節(jié) 點down了的時候接管IP)等等。

13、memcached如何處理容錯的?

在節(jié)點失效的情況下,集群沒有必要做任何容錯處理。如果發(fā)生了節(jié)點失效,應(yīng)對的措施完全取決于用戶。

節(jié)點失效時,下面列出幾種方案供您選擇:

1)忽略它! 在失效節(jié)點被恢復(fù)或替換之前,還有很多其他節(jié)點可以應(yīng)對節(jié)點失效帶來的影響。

2)把失效的節(jié)點從節(jié)點列表中移除。做這個操作千萬要小心!在默認情況下(余數(shù)式哈希算法),客戶端添加或移除節(jié)點,會導(dǎo)致所有的緩存數(shù)據(jù)不可用!因為哈希參照的節(jié)點列表變化 了,大部分key會因為哈希值的改變而被映射到(與原來)不同的節(jié)點上。

3)啟動熱備節(jié)點,接管失效節(jié)點所占用的IP。這樣可以防止哈希紊亂(hashing chaos)。

4)如果希望添加和移除節(jié)點,而不影響原先的哈希結(jié)果,可以使用一致性哈希算法(consistent hashing)。

5)兩次哈希(reshing)。當客戶端存取數(shù)據(jù)時,如果發(fā)現(xiàn)一個節(jié)點down了,就再做一次哈希(哈希算法與前一次不同),重新選擇另一個節(jié)點(需要注意的時,客戶端并沒有把down 的節(jié)點從節(jié)點列表中移除,下次還是有可能先哈希到它)。如果某個節(jié)點時好時壞,兩次哈希的方法就有風險了,好的節(jié)點和壞的節(jié)點上都可能存在臟數(shù)據(jù)(stale data)。

14、如何將memcached中item批量導(dǎo)入導(dǎo)出?

不應(yīng)該這樣做!Memcached是一個非阻塞的服務(wù)器。任何可能導(dǎo)致memcached暫?;蛩矔r拒絕服務(wù)的操作都應(yīng)該值得深思熟慮。向memcached中批量導(dǎo)入數(shù)據(jù)往往不是您真正想要 的!想象看,如果緩存數(shù)據(jù)在導(dǎo)出導(dǎo)入之間發(fā)生了變化,您就需要處理臟數(shù)據(jù)了;如果緩存數(shù)據(jù)在導(dǎo)出導(dǎo)入之間過期了,您又怎么處理這些數(shù)據(jù)呢?

因此,批量導(dǎo)出導(dǎo)入數(shù)據(jù)并不像想象中的那么有用。不過在一個場景倒是很有用。如果您有大量的從不變化 的數(shù)據(jù),并且希望緩存很快熱(warm)起來,批量導(dǎo)入緩存數(shù)據(jù)是很有幫助的。

15、但是我確實需要把memcached中的item批量導(dǎo)出導(dǎo)入,怎么辦??

如果需要批量導(dǎo)出和導(dǎo)入,最可能的原因一般是重新生成緩存數(shù)據(jù)需要消耗很長的時間或者數(shù)據(jù)庫壞了讓您飽受痛苦。
如果一個memcached節(jié)點down了讓您很痛苦,那么必須對數(shù)據(jù)庫做一些優(yōu)化工作。比如處理"驚群"問題( memcached節(jié)點都失效了,反復(fù)的查詢讓數(shù)據(jù)庫不堪重負)或者存在優(yōu)化不 好的查詢等。Memcached 并不是逃避優(yōu)化查詢的借口和方案。

這里給出一些提示:

使用MogileFS(或者CouchDB等類似的軟件)在存儲item,把item計算出來并dump到磁盤上。MogileFS可以很方便地覆寫item,并提供快速地訪問。甚至可以把MogileFS中的item 緩存在memcached中,這樣可以加快讀取速度。 MogileFS+Memcached的組合可以加快緩存不命中時的響應(yīng)速度,提高網(wǎng)站的可用性。 重新使用MySQL。MySQL的 InnoDB主鍵查詢速度非常快。如果大部分緩存數(shù)據(jù)都可以放到VARCHAR字段中,那么主鍵查詢的性能將更好。從memcached中按key查詢幾乎等價于 MySQL的主鍵查詢:將key 哈希到64-bit的整數(shù),然后將數(shù)據(jù)存儲到MySQL中。您可以把原始(不做哈希)的key存儲都普通的字段中,然后建立二級索引來加快查詢...key被動地失效, 批量刪除失效的key,等等。

16、memcached是如何做身份驗證的?

沒有身份認證機制!memcached是運行在應(yīng)用下層的軟件(身份驗證應(yīng)該是應(yīng)用上層的職責)。memcached的客戶端和服務(wù)器端之所以是輕量級的,部分原因就是完全沒有實現(xiàn)身份驗 證機制。這樣,memcached可以很快地創(chuàng)建新連接,服務(wù)器端也無需任何配置。如果您希望限制訪問,您可以使用防火墻,或者讓memcached監(jiān)聽unix domain socket。

17、memcached的多線程是什么?如何使用它們?

線程就是定律(threads rule)!在Steven Grimm和Facebook的努力下,memcached 1.2及更高版本擁有了多線程模式。多線程模式允許memcached能夠充分利用多個CPU,并在 CPU之間共享所有的緩存數(shù)據(jù)。memcached使用一種簡單的鎖機制來保證數(shù)據(jù)更新操作的互斥。相比在同一個物理機器上運行多個memcached實例,這種方式能夠更有效地處理multi gets。如果系統(tǒng)的負載并不重,那么不需要啟用多線程工作模式。如果您在運行一個擁有大規(guī)模硬件的、龐大的網(wǎng)站,將體驗到看到多線程的好處。更多信息請參見:

http://code.sixapart.com/svn/memcached/trunk/server/doc/threads.txt 。

簡單地總結(jié)一下:命令解析(memcached在這里花了大部分時間)可以運行在多線程模式下。memcached內(nèi)部對數(shù)據(jù)的操作是基于很多全局鎖的(因此這部分工作不是多線程的)。未 來對多線程模式的改進,將移除大量的全局鎖,提高memcached在負載極高的場景下的性能。

18、memcached能接受的key的長度是多少?

memcached能接受的key的長度是250個字符。需要注意的是,250是memcached服務(wù)器端內(nèi)部的限制。如果使用的Memcached客戶端支持"key的前綴"或類似特性,那么key (前綴+原始key)的長度是可以超過250個字符的。推薦使用較短的key,這樣可以節(jié)省內(nèi)存和帶寬。

19、memcached對item的過期時間有什么限制?

item對象的過期時間最長可以達到30天。memcached把傳入的過期時間(時間段)解釋成時間點后,一旦到了這個時間點,memcached就把item置為失效狀態(tài),這是一個簡單但 obscure的機制。

20、memcached能存儲多大的單個item?

memcached能存儲1MB的單個item。如果需要被緩存的數(shù)據(jù)大于1MB,可以考慮在客戶端壓縮或拆分到多個key中。

21、為什么單個item的大小被限制在1M byte之內(nèi)?

簡單的回答:因為內(nèi)存分配器的算法就是這樣的。

詳細的回答:

1)Memcached的內(nèi)存存儲引擎,使用slabs來管理內(nèi)存。內(nèi)存被分成大小不等的slabs chunks(先分成大小相等的slabs,然后每個slab被分成大小相等chunks,不同slab的chunk大小 是不相等的)。chunk的大小依次從一個最小數(shù)開始,按某個因子增長,直到達到的可能值。如果最小值為400B,值是1MB,因子是1.20,各個slab的chunk的大小依次是:

slab1 - 400B;slab2 - 480B;slab3 - 576B ...slab中chunk越大,它和前面的slab之間的間隙就越大。因此,值越大,內(nèi)存利用率越低。Memcached必須為每個slab預(yù)先分配內(nèi) 存,因此如果設(shè)置了較小的因子和較大的值,會需要為Memcached提供更多的內(nèi)存。

2)不要嘗試向memcached中存取很大的數(shù)據(jù),例如把巨大的網(wǎng)頁放到mencached中。因為將大數(shù)據(jù)load和unpack到內(nèi)存中需要花費很長的時間,從而導(dǎo)致系統(tǒng)的性能反而不好。如果

確實需要存儲大于1MB的數(shù)據(jù),可以修改slabs.c:POWER_BLOCK的值,然后重新編譯memcached;或者使用低效的malloc/free。另外,可以使用數(shù)據(jù)庫、MogileFS等方案代替 Memcached系統(tǒng)。

22、可以在不同的memcached節(jié)點上使用大小不等的緩存空間嗎?如果這么做之后,memcached能夠更有效地使用內(nèi)存嗎?

Memcache客戶端僅根據(jù)哈希算法來決定將某個key存儲在哪個節(jié)點上,而不考慮節(jié)點的內(nèi)存大小。因此,可以在不同的節(jié)點上使用大小不等的內(nèi)存作為緩存空間。但是一般可以這樣做 :擁有較多內(nèi)存的節(jié)點上可以運行多個memcached實例,每個實例使用的內(nèi)存跟其他節(jié)點上的實例相同。

23、什么是二進制協(xié)議,是否需要關(guān)注?

二進制協(xié)議嘗試為端提供一個更有效的、可靠的協(xié)議,減少客戶端/服務(wù)器端因處理協(xié)議而產(chǎn)生的CPU時間。根據(jù)Facebook的測試,解析ASCII協(xié)議是memcached中消耗CPU時間最多的 環(huán)節(jié)。

24、memcached的內(nèi)存分配器是如何工作的?為什么不適用malloc/free!?為何要使用slabs?

實際上,這是一個編譯時選項。默認會使用內(nèi)部的slab分配器,而且確實應(yīng)該使用內(nèi)建的slab分配器。最早的時候,memcached只使用malloc/free來管理內(nèi)存。然而,這種方式不能與 OS的內(nèi)存管理以前很好地工作。反復(fù)地malloc/free造成了內(nèi)存碎片,OS最終花費大量的時間去查找連續(xù)的內(nèi)存塊來滿足malloc的請求,而不是運行memcached進程。slab分配器就是 為了解決這個問題而生的。內(nèi)存被分配并劃分成chunks,一直被重復(fù)使用。因為內(nèi)存被劃分成大小不等的slabs,如果item的大小與被選擇存放它的slab不是很合適的話,就會浪費一些內(nèi)存。

25、memcached是原子的嗎?

所有的被發(fā)送到memcached的單個命令是完全原子的。如果您針對同一份數(shù)據(jù)同時發(fā)送了一個set命令和一個get命令,它們不會影響對方。它們將被串行化、先后執(zhí)行。即使在多線程模 式,所有的命令都是原子的。然是,命令序列不是原子的。如果首先通過get命令獲取了一個item,修改了它,然后再把它set回memcached,系統(tǒng)不保證這個item沒有被其他進程 (process,未必是操作系統(tǒng)中的進程)操作過。memcached 1.2.5以及更高版本,提供了gets和cas命令,它們可以解決上面的問題。如果使用gets命令查詢某個key的item, memcached會返回該item當前值的唯一標識。如果客戶端程序覆寫了這個item并想把它寫回到memcached中,可以通過cas命令把那個唯一標識一起發(fā)送給memcached。如果該item 存放在memcached中的唯一標識與您提供的一致,寫操作將會成功。如果另一個進程在這期間也修改了這個item,那么該item存放在memcached中的唯一標識將會改變,寫操作就會 失敗。

性能和客戶端庫方面的問題

26、memcached沒有我的database快,為什么?

在一對一比較中,memcached可能沒有SQL查詢快。但是,這不是memcached的設(shè)計目標。Memcached的目標是可伸縮性。當連接和請求增加的時候,memcached的性能將比 大多數(shù)數(shù)據(jù)庫查詢好??梢韵仍诟哓撦d的環(huán)境(并發(fā)的連接和請求)中測試您的代碼,然后再決定memcached是否適合您。

27、使用不同的客戶端庫,可以訪問到memcached中相同的數(shù)據(jù)嗎?

從技術(shù)上說,是可以的。但是可能會遇到下面三個問題:

1)不同的庫采用不同的方式序列化數(shù)據(jù)。舉個例子,perl的Cache::Memcached使用Storable來序列化結(jié)構(gòu)復(fù)雜的數(shù)據(jù)(比如hash references, objects, 等)。其他語言的客戶端庫很 可能不能讀取這種格式的數(shù)據(jù)。如果您要存儲復(fù)雜的數(shù)據(jù)并且想被多種客戶端庫讀取,那么您應(yīng)該以簡單的string格式來存儲,并且這種格式可以被JSON、XML等外部庫解析。

2)從某個客戶端來的數(shù)據(jù)被壓縮了,從另一個客戶端來的卻沒被壓縮。

3)各個客戶端庫可能使用不同的哈希算法(階段一哈希)。在連接到多個memcached服務(wù)器端的情況下,客戶端庫根據(jù)自身實現(xiàn)的哈希算法把key映射到某臺memcached上。正是因為

不同的客戶端庫使用不同的哈希算法,所以被Perl客戶端庫映射到memcached A的key,可能又會被Python客戶端庫映射到memcached B,等等。Perl客戶端庫還允許為每臺 memcached指定不同的權(quán)重(weight),這也是導(dǎo)致這個問題的一個因素。

28、什么是一致性哈希的客戶端?

這里有一篇文章很好地解釋了它的用處:http://www.last.fm/user/RJ/journal/2007/04/10/392555 。

客戶端可以通過"前綴"來給key設(shè)置一個域(命名空間)。例如,在一個共享主機的環(huán)境中,可以將客戶姓名作為"前綴",為key創(chuàng)建一個特定的域。在存儲數(shù)據(jù)的時候,"前綴"可以用在 key上,但是不應(yīng)該參與哈希計算。目前,memcached自己還沒有實現(xiàn)針對復(fù)雜結(jié)構(gòu)數(shù)據(jù)的序列化方法,JSON則是一種被廣泛使用的對象序列化格式。

哈希 / 鍵分布

29、什么時候失效的數(shù)據(jù)項會從緩存中刪除?

memcached 使用懶失效,當客戶端請求數(shù)據(jù)項時, memcached 在返回數(shù)據(jù)前會檢查失效時間來確定數(shù)據(jù)項是否已經(jīng)失效。同樣地,當添加一個新的數(shù)據(jù)項時,如果緩存已經(jīng)滿了, memcached 就會先替換失效的數(shù)據(jù)項,然后才是緩存中最少使用的數(shù)據(jù)項。

命名空間

30、memcached 不支持命名空間。以下提供幾種模仿命名空間的方式:

1)用鍵的前綴模仿命名空間:在真實的鍵之前加入有意義的前綴。

2)用命名空間刪除數(shù)據(jù)項:盡管 memcached 不支持使用任何類型的通配符或命名空間來完成刪除操作,但是可以采用一些技巧來替代:

在 PHP 中使用一個叫 foo 的命名空間:$ns_key = $memcache-&gt;get("foo_namespace_key");

// if not set, initialize it

if($ns_key=false) $memcache-&gt;set("foo_namespace_key", rand(1, 10000));

$my_key = "foo_".$ns_key."_12345";

清除命名空間:$memcache-&gt;increment("foo_namespace_key");

應(yīng)用設(shè)計

31、在設(shè)計應(yīng)用時,可以通過Memcached緩存那些內(nèi)容?

1)緩存簡單的查詢結(jié)果:查詢緩存存儲了給定查詢語句對應(yīng)的整個結(jié)果集,最合適緩存那些經(jīng)常被用到,但不會改變的 SQL 語句對查詢到的結(jié)果集,比如載入特定的過濾內(nèi)容。

$key = md5(\'SELECT * FROM rest_of_sql_statement_goes_here\');

if ($memcache-&gt;get($key)) {

` return $memcache-&gt;get($key);`

}else {

` // Run the query and transform the result data into your final dataset form`

` $result = $query_results_mangled_into_most_likely_an_array`

` $memcache-&gt;set($key, $result, TRUE, 86400); // Store the result of the query for a day`

` return $result;`

}

記住,如果查詢語句對應(yīng)的結(jié)果集改變,該結(jié)果集不會展現(xiàn)出來。這種方法不總是有用,但它確實讓工作變得比較快。

2)緩存簡單的基于行的查詢結(jié)果:基于行的緩存會檢查緩存數(shù)據(jù)key的列表,那些在緩存中的行可以直接被取出,不在緩存中的行將會從數(shù)據(jù)庫中取出并以唯一的鍵為標識緩存起來,最

后加入到最終的數(shù)據(jù)集中返回。隨著時間的推移,大多數(shù)數(shù)據(jù)都會被緩存,這也意味著相比與數(shù)據(jù)庫,查詢語句會更多地從 memcached 中得到數(shù)據(jù)行。如果數(shù)據(jù)是相當靜態(tài)的,我們可 以設(shè)置一個較長的緩存時間。
基于行的緩存模式對下面這種搜索情況特別有用:數(shù)據(jù)集本身很大或是數(shù)據(jù)集是從多張表中得到,而數(shù)據(jù)集取決于查詢的輸入?yún)?shù)但是查詢的結(jié)果集之間的有重復(fù)部分。 比如,如果你有用戶 A , B , C , D , E 的數(shù)據(jù)集。你去點擊一張顯示用戶 A , B , E 信息的頁面。首先, memcached 得到 3 個不同的鍵,每個對應(yīng)一個用戶去緩存中查找,全部未 命中。然后就到數(shù)據(jù)庫中用 SQL 查詢得到 3 個用戶的數(shù)據(jù)行,并緩存他們。 現(xiàn)在,你又去點擊另一張顯示顯示 C , D , E 信息的頁面。當你去查找 memcached 時, C , D 的數(shù)據(jù)并沒有被命中,但我們命中了 E 的數(shù)據(jù)。然后從數(shù)據(jù)庫得到 C , D 的行數(shù)據(jù),緩 存在 memcached 中。至此以后,無論這些用戶信息怎樣地排列組合,任何關(guān)于 A , B , C , D , E 信息的頁面都可以從 memcached 得到數(shù)據(jù)了。

3)緩存的不只是 SQL 數(shù)據(jù),可以緩存最終完成的部分顯示頁面,以節(jié)省CPU計算時間

例如正在制作一張顯示用戶信息的頁面,你可能得到一段關(guān)于用戶的信息(姓名,生日,家庭住址,簡介),然后你可能會將 XML 格式的簡介信息轉(zhuǎn)化為 HTML 格式或做其他的一些工 作。相比單獨存儲這些屬性,你可能更愿意存儲經(jīng)過渲染的數(shù)據(jù)塊。那時你就可以簡單地取出被預(yù)處理后的 HTML 直接填充在頁面中,這樣節(jié)省了寶貴的 CPU 時間。

32、使用分層的緩存

memcached 可以高速處理大量的緩存數(shù)據(jù),但是還是要根據(jù)系統(tǒng)的情況考慮維護多層的緩存結(jié)構(gòu)。例如除了memcached緩存之外,還可以通過本地緩存(如ehcache、oscache等)建 立起多級緩存。例如,可以采用本地緩存緩存一些基本數(shù)據(jù),例如少量但訪問頻繁的數(shù)據(jù)(如產(chǎn)品分類,連接信息,服務(wù)器狀態(tài)變量,應(yīng)用配置變量等),緩存這些數(shù)據(jù)并讓他們盡可能的 接近處理器是有意義的 , 這樣可以幫助減少生成頁面的時間,并且在 memcached 失效的情況下可以增加可靠性。

33、當數(shù)據(jù)更新時需要更新緩存

用戶編輯了自己的信息,當保存信息到數(shù)據(jù)庫時,需要更新緩存中的數(shù)據(jù)或是簡單地刪除老的數(shù)據(jù)。如果馬上更新數(shù)據(jù),要防止從數(shù)據(jù)庫讀取那些剛剛更新過的數(shù)據(jù)。當用戶習慣性地重新 載入自己的用戶信息來確認是否修改成功時,數(shù)據(jù)將從緩存中直接取出,這時他們獲得了最新的數(shù)據(jù)。

34、模擬帶鎖的添加命令

如果你實在需要鎖,你可以通過“添加”命令模仿鎖的功能。盡管在未命中的情況下它不是那么有用,但如果你用它緩存平常的數(shù)據(jù)(應(yīng)用服務(wù)器池的元數(shù)據(jù))那還是有用的。

比如,你要更新鍵 A 。

1. 添加一個 "lock:A" 的鍵,這個鍵有一個持續(xù)幾秒的過期時間(足夠長以使你能完成計算和更新,也不要很長,因為如果鎖進程掛了,這個鍵不會立即釋放)

2. 如果添加操作成功了,你就擁有了鎖:從緩存獲取鍵 A 的數(shù)據(jù);利用客戶端程序更改數(shù)據(jù);更新緩存鍵 A 的數(shù)據(jù);刪除鍵 "lock:A" 。如果你不需要立即再次更新,就讓它存活直到失效。

3. 如果添加操作失敗,說明有人獲取了鎖。這時讓應(yīng)用做些合適的事,比如返回老數(shù)據(jù),等待后重試,或是其他的。

以上這些操作類似 MySQL 將 GET_LOCK 的 timeout 值設(shè)置成 0 。沒有辦法在 memcached 中通過互斥鎖模擬 GET_LOCK() 的 timeout 操作。

35、預(yù)熱你的緩存

如果你有一個很高訪問率的站點,并且你正想加入故障恢復(fù)功能或是其他全新的功能,你最終可能會碰到空緩存的問題。一開始緩存是空的,然后一大群人點擊你的站點,在填充緩存的過 程中,你的數(shù)據(jù)庫可能會承受不住壓力。為了解決這一問題,你可以試試任何可行的方法來 " 溫暖 " 你的Memcached。方法:可以寫一些腳本來緩存通用的頁面;也可以寫一個命令行工 具來填充緩存。你可以在高峰時刻在緩存里填充一些內(nèi)容。

分享標題:memcache雜談
文章路徑:http://www.muchs.cn/article40/cjhheo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設(shè)定制網(wǎng)站、網(wǎng)站維護網(wǎng)站設(shè)計公司、網(wǎng)站建設(shè)、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

猜你還喜歡下面的內(nèi)容

成都網(wǎng)站建設(shè)

ChatGPT知識

各行業(yè)網(wǎng)站