成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Memcache 學(xué)習(xí)總結(jié)

zhonghanwen / 1405人閱讀

摘要:余數(shù)分布式算法就是根據(jù)服務(wù)器臺數(shù)的余數(shù)進(jìn)行分散。余數(shù)分布式算法由于保存鍵的服務(wù)器會發(fā)生巨大變化,而影響緩存的命中率,但中,只有在上增加服務(wù)器的地點(diǎn)逆時針方向的第一臺服務(wù)器上的鍵會受到影響。

WHAT is Memcache?

Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.
memcached是一個免費(fèi)開源、高性能、分布式的內(nèi)存對象緩存系統(tǒng),本質(zhì)上是通用的,但旨在通過加速動態(tài)Web應(yīng)用程序來減輕數(shù)據(jù)庫負(fù)載。

Memcache是一款開發(fā)工具,其設(shè)計思想主要反映以下幾個方面:

簡單的key/value存儲:服務(wù)器不關(guān)心數(shù)據(jù)本身意義及結(jié)構(gòu),主要是可序列化數(shù)據(jù)即可。

功能實(shí)現(xiàn)一半依賴與客戶端,一半基于服務(wù)器端。

各服務(wù)器間彼此無視,不在服務(wù)器間進(jìn)行數(shù)據(jù)同步。

O(1)的執(zhí)行效率。

內(nèi)存空間的再利用,Lazy Expiration + LRU 機(jī)制。

Memcache 與 memcached的區(qū)別

1.客戶端兩者區(qū)別:

兩個不同版本PHP的memcached的客戶端

memcache是原生版本,完全是在PHP框架內(nèi)開發(fā)的,支持OO和非OO兩套接口并存;而memcached是建立在libmemcached的基礎(chǔ)上,只支持OO接口。

其他一些實(shí)現(xiàn)和支持方面的不同等。

2.服務(wù)器端兩者區(qū)別:

Memcache 是項(xiàng)目名稱

Memcached 是Memcache服務(wù)器端可執(zhí)行文件的名稱,Memcached是以守護(hù)程序(監(jiān)聽)方式運(yùn)行于一個或多個服務(wù)器中,隨時會接收客戶端的連接和操作。

ps:本文說明的內(nèi)容是關(guān)于memcache服務(wù)器的,請不要跟客戶端的叫法混淆。

Memcached內(nèi)置內(nèi)存存儲方式

1. Memcached 的高性能

首先從內(nèi)存模型來研究memcached:C++里分配內(nèi)存有兩種方式,預(yù)先分配和動態(tài)分配內(nèi)存,顯然預(yù)先分配內(nèi)存會使程序比較快,但是它的缺點(diǎn)是不能有效利用內(nèi)存;而動態(tài)分配可以有效利用內(nèi)存,但是會使程序運(yùn)行效率下降,memcached的內(nèi)存分配就是基于以上原理,顯然為了獲得更快的速度,有時候我們不得不以空間換時間。
Memcached的高性能源于兩階段哈希(two-stage-hash)結(jié)構(gòu)。Memcached就像一個巨大的、存儲了很多對的哈希表,通過key可以存儲或查詢?nèi)我獾臄?shù)據(jù)。客戶端可以把數(shù)據(jù)存儲在多臺memcached上,當(dāng)查詢數(shù)據(jù)時,客戶端首先參考節(jié)點(diǎn)列表計算出key的哈希值(階段一哈希),進(jìn)而選中一個節(jié)點(diǎn);客戶端將請求發(fā)送給選中的節(jié)點(diǎn),然后memcached節(jié)點(diǎn)通過一個內(nèi)部的哈希算法(階段二哈希),查找真正的數(shù)據(jù)(item)并返回個客戶端。從實(shí)現(xiàn)的角度看,memcached是一個非阻塞、基于事件驅(qū)動的服務(wù)器程序。
為了提高性能,memcacahed中保存的數(shù)據(jù)都存儲在memcached內(nèi)置的內(nèi)存存儲空間中。由于數(shù)據(jù)僅存在于內(nèi)存中,因此重啟memcached、重啟操作系統(tǒng)會導(dǎo)致全部數(shù)據(jù)丟失。另外,內(nèi)存容量達(dá)到指定值之后,就基于LRU(Least Recently Used)算法自動刪除不使用的緩存。memcached本身是為了緩存而設(shè)計的服務(wù)器,因此并沒有過多考慮數(shù)據(jù)的永久性問題。

2. Slab Allocator 內(nèi)存分配、管理機(jī)制

1.在該機(jī)制出現(xiàn)以前,內(nèi)存的分配是通過對所有記錄簡單地進(jìn)行malloc和free 來進(jìn)行的。但是,這種方式會導(dǎo)致內(nèi)存碎片,加重操作系統(tǒng)內(nèi)存管理器的負(fù)擔(dān),最壞的情況下,會導(dǎo)致操作系統(tǒng)比memcached 進(jìn)程本身還慢。Slab Allocator 就是為解決該問題而誕生的, 它按照預(yù)先規(guī)定的大小,將分配的內(nèi)存分割成特定長度的塊,以完成解決內(nèi)存碎片的問題。存儲結(jié)構(gòu)圖如下:

Memcached的存儲涉及到slab、page、chunk三個概念
chunk:固定大小的內(nèi)存空間,用于緩存記錄,默認(rèn)為88Byte。
page:分配給Slab的內(nèi)存空間,默認(rèn)是1M。分配給Slab之后根據(jù)Slab的大小切成chunk。
slab:同樣大小的chunk組成一類slab。

2.在Slab中緩存記錄的原理
memcached 根據(jù)收到的數(shù)據(jù)大小,選擇最適合數(shù)據(jù)大小的Slab,memcached中保存著Slab內(nèi)空閑chunk的列表,根據(jù)該列表選擇chunk,然后將數(shù)據(jù)緩存其中。Slab allocator分配的內(nèi)存不會釋放,而是重復(fù)利用。

3.Slab Allocator 的缺點(diǎn)
由于分配的是特定長度的內(nèi)存,因此無法有效的利用分配的內(nèi)存。對與該問題沒有完美的解決方案,但可以調(diào)節(jié)slab class的大小差別來減少空間浪費(fèi)。

4.使用Growth Factor進(jìn)行調(diào)優(yōu)
memcached在啟動時制定Growth Factor因子(通過f選項(xiàng)),就可以在某種程度上控制slab之間的差異。默認(rèn)值時1.25.

Memcached 刪除機(jī)制

memcached是緩存,不需要永久的保存到服務(wù)器上,下面介紹它的刪除機(jī)制:
1.Lazy Expiration
memcached 不會釋放已經(jīng)分配的內(nèi)存,記錄過期后,客戶端無法在看到這條記錄,其存儲空間可以再利用。memcached內(nèi)部不會監(jiān)視記錄是否過期,而是在get時查看記錄的時間戳,檢查記錄是否過期。這種技術(shù)被稱為Lazy Expiration。因此,memcached不會在過期監(jiān)視上耗費(fèi)CPU時間。

2.LRU(Least Recently Used)
memcached會優(yōu)先使用已超時的記錄空間,但即使如此,也會發(fā)生追加新記錄時空間不足的情況,此時就要使用名為LRU機(jī)制來分配空間。顧名思義,這是刪除“最近最少使用”記錄的機(jī)制。因此,當(dāng)memcahced的內(nèi)存空間不足時(無法從slab class獲取新的空間時),就從最近未被使用的記錄中搜索,并將其空間分配給新的記錄。

Memcached 分布式算法

1.Memcached "分布式"

特別澄清一個問題:MemCache雖然被稱為"分布式緩存",但是MemCache本身完全不具備分布式的功能,Memcache集群之間不會相互通信(與之形成對比的,比如JBoss Cache,某臺服務(wù)器有緩存數(shù)據(jù)更新時,會通知集群中其他機(jī)器更新緩存或清除緩存數(shù)據(jù)),所謂的"分布式",完全依賴于客戶端程序的實(shí)現(xiàn)。前面已經(jīng)講過memcached的兩段哈希了,數(shù)據(jù)的保存和獲取都使用相同的算法。這樣將不同的鍵保存到不同的服務(wù)器上,就實(shí)現(xiàn)了memcached的分布式。Memcached服務(wù)器增多后,鍵就會分散,即使一臺memcached服務(wù)器發(fā)生故障無法連接,也不會影響其他的緩存,系統(tǒng)依然能繼續(xù)進(jìn)行。

2.余數(shù)分布式算法

就是“根據(jù)服務(wù)器臺數(shù)的余數(shù)進(jìn)行分散”。求得鍵的整數(shù)哈希值,再除以服務(wù)器臺數(shù),根據(jù)其余數(shù)來選擇服務(wù)器。
余數(shù)算法的缺點(diǎn):余數(shù)計算的方法簡單,數(shù)據(jù)的分散性也相當(dāng)優(yōu)秀,但也有其缺點(diǎn)。那就是當(dāng)添加或移除服務(wù)器時,緩存重組的代價相當(dāng)巨大。添加服務(wù)器后,余數(shù)就會產(chǎn)生巨變,這樣就無法獲取與保存時相同的服務(wù)器,從而影響緩存的命中率。

3.Consistent hashing(一致哈希)

首先求出memcached 服務(wù)器(節(jié)點(diǎn))的哈希值,并將其配置到0~2^32-1 的圓(continuum)上。然后用同樣的方法求出存儲數(shù)據(jù)的鍵的哈希值,并映射到圓上。然后從數(shù)據(jù)映射到的位置開始順時針查找,將數(shù)據(jù)保存到找到的第一個服務(wù)器上。如果超過2^32-1仍然找不到服務(wù)器,就會保存到第一臺memcached 服務(wù)器上。

從上圖的狀態(tài)中添加一臺Memcached 服務(wù)器。余數(shù)分布式算法由于保存鍵的服務(wù)器會發(fā)生巨大變化,而影響緩存的命中率,但Consistent Hashing中,只有在continuum 上增加服務(wù)器的地點(diǎn)逆時針方向的第一臺服務(wù)器上的鍵會受到影響。

Consistent Hashing(添加服務(wù)器):
因此,Consistent Hashing 最大限度地抑制了鍵的重新分布。而且,有的Consistent Hashing 的實(shí)現(xiàn)方法還采用了虛擬節(jié)點(diǎn)的思想。使用一般的hash函數(shù)的話,服務(wù)器的映射地點(diǎn)的分布非常不均勻。因此,使用虛擬節(jié)點(diǎn)的思想,為每個物理節(jié)點(diǎn)(服務(wù)器)在continum上分配100~200 個點(diǎn)。這樣就能抑制分布不均勻,最大限度地減小服務(wù)器增減時的緩存重新分布。
通過上文中介紹的使用Consistent Hashing 算法的Memcached 客戶端函數(shù)庫進(jìn)行測試的結(jié)果是,由服務(wù)器臺數(shù)(n)和增加的服務(wù)器臺數(shù)(m)計算增加服務(wù)器后的命中率計算公式: (1 -m/(n+m)) * 100

常用命令介紹

1.存儲及刪除命令,簡單易用,使用語法如下:
command

參數(shù)說明如下:
command set/add/replace
key key 用于查找緩存值
flags 可以包括鍵值對的整型參數(shù),客戶機(jī)使用它存儲關(guān)于鍵值對的額外信息
expiration time 在緩存中保存鍵值對的時間長度(以秒為單位,0 表示永遠(yuǎn))
bytes 在緩存中存儲的字節(jié)數(shù)
value 存儲的值(始終位于第二行)

set 命令用于向緩存添加新的鍵值對,如果已經(jīng)存在,則之前的值將被替換。設(shè)置成功,服務(wù)器會使用單詞STORED進(jìn)行響應(yīng)。

add 僅當(dāng)緩存中不存在鍵時,add 命令才會向緩存中添加一個鍵值對。如果緩存中已經(jīng)存在鍵,則之前的值將仍然保持相同,并且您將獲得響應(yīng) NOT_STORED。

replace 僅當(dāng)鍵已經(jīng)存在時,replace 命令才會替換緩存中的鍵。如果緩存中不存在鍵,那么您將從 memcached 服務(wù)器接受到一條 NOT_STORED 響應(yīng)。

delete 刪除命令的語法:command ,delete 命令用于刪除 memcached 中的任何現(xiàn)有值。您將使用一個鍵調(diào)用delete,如果該鍵存在于緩存中,則刪除該值。如果不存在,則返回一條NOT_FOUND 消息。

2.讀取命令

get 命令用于檢索與之前添加的鍵值對相關(guān)的值。當(dāng)使用一個鍵來調(diào)用 get,如果這個鍵存在于緩存中,則返回相應(yīng)的值。如果不存在,則不返回任何內(nèi)容。get命令的key可以表示一個或者多個鍵,鍵之間以空格隔開。

gets 命令比普通的get命令多返回一個數(shù)字。這個數(shù)字可以檢查數(shù)據(jù)是否發(fā)生變化:當(dāng)key對應(yīng)的數(shù)據(jù)變化時,這個數(shù)字也會改變。

cas 即check and set,只有當(dāng)最后一個參數(shù)和gets所獲取的參數(shù)匹配時才能存儲,否則返回“EXISTS”。

3.統(tǒng)計命令

stats 顯示服務(wù)器信息、統(tǒng)計數(shù)據(jù)

stats settings 顯示所有的參數(shù)設(shè)置

stats slabs 顯示各個slab的信息,包括chunk的大小、數(shù)目、使用情況等

stats items 顯示各個slab的item信息

stats cachedump slab_id limit_num 查看指定slab前l(fā)imit_num個item,[key,expiration_time]

flush_all 用于清理緩存中所有鍵值對

stats reset 清空統(tǒng)計數(shù)據(jù)

運(yùn)行狀態(tài)分析

1.stats指令解讀

stats是一個比較重要的指令,用于列出當(dāng)前MemCache服務(wù)器的狀態(tài),返回的參數(shù)反映著Memcache服務(wù)器的基本信息,他們的意思是:

參 ?數(shù) ?名 作 ? ? ?用
pid MemCache服務(wù)器的進(jìn)程id?
uptime 服務(wù)器已經(jīng)運(yùn)行的秒數(shù)
time 服務(wù)器當(dāng)前的UNIX時間戳?
version MemCache版本?
pointer_size 當(dāng)前操作系統(tǒng)指針大小,反映了操作系統(tǒng)的位數(shù),64意味著MemCache服務(wù)器是64位的?
rusage_user 進(jìn)程的累計用戶時間?
rusage_system? 進(jìn)程的累計系統(tǒng)時間?
curr_connections? ?當(dāng)前打開著的連接數(shù)
total_connections ? ?當(dāng)服務(wù)器啟動以后曾經(jīng)打開過的連接數(shù)
connection_structures? 服務(wù)器分配的連接構(gòu)造數(shù)?
cmd_get? get命令總請求次數(shù)?
cmd_set set命令總請求次數(shù)?
cmd_flush flush_all命令總請求次數(shù)?
get_hits 總命中次數(shù),重要,緩存最重要的參數(shù)就是緩存命中率,以get_hits / (get_hits + get_misses)表示,比如這個緩存命中率就是99.2%?
get_misses? 總未命中次數(shù)?
auth_cmds? 認(rèn)證命令的處理次數(shù)?
auth_errors? 認(rèn)證失敗的處理次數(shù)?
bytes_read? 總讀取的字節(jié)數(shù)
bytes_written? 總發(fā)送的字節(jié)數(shù)?
?limit_maxbytes 分配給MemCache的內(nèi)存大?。▎挝粸樽止?jié))?
accepting_conns? 是否已經(jīng)達(dá)到連接的最大值,1表示達(dá)到,0表示未達(dá)到
listen_disabled_num? 統(tǒng)計當(dāng)前服務(wù)器連接數(shù)曾經(jīng)達(dá)到最大連接的次數(shù),這個次數(shù)應(yīng)該為0或者接近于0,如果這個數(shù)字不斷增長, 就要小心我們的服務(wù)了
threads? 當(dāng)前MemCache總線程數(shù),由于MemCache的線程是基于事件驅(qū)動機(jī)制的,因此不會一個線程對應(yīng)一個用戶請求?
bytes? 當(dāng)前服務(wù)器存儲的items總字節(jié)數(shù)
current_items? 當(dāng)前服務(wù)器存儲的items總數(shù)量?
total_items? 自服務(wù)器啟動以后存儲的items總數(shù)量?

比較關(guān)注的點(diǎn):get_hits 和 get_misses,命中率:get_hits/(get_hits + get_misses) 是衡量memcache服務(wù)器的一個重要指標(biāo)。

2.stats slabs 指令解讀

參 ?數(shù) ?名 作 ? ? ?用
chunk_size 當(dāng)前slab每個chunk的大小,單位為字節(jié)
chunks_per_page 每個page可以存放的chunk數(shù)目,由于每個page固定為1M即10241024字節(jié),所以這個值就是(10241024/chunk_size)
total_pages 分配給當(dāng)前slab的page總數(shù)
total_chunks 當(dāng)前slab最多能夠存放的chunk數(shù),這個值是total_pages*chunks_per_page
used_chunks 已經(jīng)被分配給存儲對象的chunks數(shù)目
free_chunks 曾經(jīng)被使用過但是因?yàn)檫^期而被回收的chunk數(shù)
free_chunks_end 新分配但還沒有被使用的chunk數(shù),這個值不為0則說明當(dāng)前slab從來沒有出現(xiàn)過容量不夠的時候
mem_requested 當(dāng)前slab中被請求用來存儲數(shù)據(jù)的內(nèi)存空間字節(jié)總數(shù),(total_chunks*chunk_size)-mem_requested表示有多少內(nèi)存在當(dāng)前slab中是被閑置的,這包括未用的slab+使用的slab中浪費(fèi)的內(nèi)存
get_hits 當(dāng)前slab中命中的get請求數(shù)
cmd_set 當(dāng)前slab中接收的所有set命令請求數(shù)
delete_hits 當(dāng)前slab中命中的delete請求數(shù)
incr_hits 當(dāng)前slab中命中的incr請求數(shù)
decr_hits 當(dāng)前slab中命中的decr請求數(shù)
cas_hits 當(dāng)前slab中命中的cas請求數(shù)
cas_badval 當(dāng)前slab中命中但是更新失敗的cas請求數(shù)

通過此命令返回的信息,可以查看slab class的分布情況,以及每個slab中chunk使用情況;根據(jù)slab的分布,可以判斷增長因子的設(shè)置的是否合理等。

3.stats items 命令解讀

參數(shù)名 作用
outofmemory slab class為新item分配空間失敗的次數(shù)。這意味著你運(yùn)行時帶上了-M或者移除操作失敗
number 存放的數(shù)據(jù)總數(shù)
age 存放的數(shù)據(jù)中存放時間最久的數(shù)據(jù)已經(jīng)存在的時間,以秒為單位
evicted 不得不從LRU中移除未過期item的次數(shù)?
evicted_time 自最后一次清除過期item起所經(jīng)歷的秒數(shù),即最后被移除緩存的時間,0表示當(dāng)前就有被移除,用這個來判斷數(shù)據(jù)被移除的最近時間
evicted_nonzero 沒有設(shè)置過期時間(默認(rèn)30天),但不得不從LRU中清除該未過期的item的次數(shù)

因?yàn)閙emcached的內(nèi)存分配策略導(dǎo)致一旦memcached的總內(nèi)存達(dá)到了設(shè)置的最大內(nèi)存,表示所有的slab能夠使用的page都已經(jīng)固定,這時如果還有數(shù)據(jù)放入,將導(dǎo)致memcached使用LRU策略剔除數(shù)據(jù)。而LRU策略不是針對所有的slabs,而是只針對新數(shù)據(jù)應(yīng)該被放入的slab,例如有一個新的數(shù)據(jù)要被放入slab 3,則LRU只對slab 3進(jìn)行,通過stats items就可以觀察到這些剔除的情況。
注意evicted_time:并不是發(fā)生了LRU就代表memcached負(fù)載過載了,因?yàn)橛行r候在使用cache時會設(shè)置過期時間為0,這樣緩存將被存放30天,如果內(nèi)存滿了還持續(xù)放入數(shù)據(jù),而這些為過期的數(shù)據(jù)很久沒有被使用,則可能被剔除。把evicted_time換算成標(biāo)準(zhǔn)時間看下是否已經(jīng)達(dá)到了你可以接受的時間,例如:你認(rèn)為數(shù)據(jù)被緩存了2天是你可以接受的,而最后被剔除的數(shù)據(jù)已經(jīng)存放了3天以上,則可以認(rèn)為這個slab的壓力其實(shí)可以接受的;但是如果最后被剔除的數(shù)據(jù)只被緩存了20秒,不用考慮,這個slab已經(jīng)負(fù)載過重了。

注意問題

memcache已經(jīng)分配的內(nèi)存不會再主動清理。

memcache分配給某個slab的內(nèi)存頁不能再分配給其他slab。

flush_all不能重置memcache分配內(nèi)存頁的格局,只是給所有的item置為過期。

memcache最大存儲的item(key+value)大小限制為1M,這由page大小1M限制

由于memcache的分布式是客戶端程序通過hash算法得到的key取模來實(shí)現(xiàn),不同的語言可能會采用不同的hash算法,同樣的客戶端程序也有可能使用相異的方法,因此在多語言、多模塊共用同一組memcached服務(wù)時,一定要注意在客戶端選擇相同的hash算法

啟動memcached時可以通過-M參數(shù)禁止LRU替換,在內(nèi)存用盡時add和set會返回失敗

memcached啟動時指定的是數(shù)據(jù)存儲量,沒有包括本身占用的內(nèi)存、以及為了保存數(shù)據(jù)而設(shè)置的管理空間。因此它占用的內(nèi)存量會多于啟動時指定的內(nèi)存分配量,這點(diǎn)需要注意。

memcache存儲的時候?qū)ey的長度有限制,php和C的最大長度都是250

參考文檔

https://www.cnblogs.com/xrq73...
http://zhihuzeye.com/archives...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/61738.html

相關(guān)文章

  • PHP面試總結(jié)

    摘要:而在面試過程中,也是經(jīng)常會遇到的,所以,無論是面試準(zhǔn)備還是日常開發(fā),我們都應(yīng)該關(guān)注這方面的東西。二分法的基本做法是確定要查找的區(qū)間。區(qū)間內(nèi)選取二分點(diǎn)。根據(jù)二分點(diǎn)的值,綜合左右區(qū)間情況以及求解的目的,舍去一半無用的區(qū)間。 showImg(https://images.pexels.com/photos/935977/pexels-photo-935977.jpeg); 前言 面試是你進(jìn)入...

    alin 評論0 收藏0
  • Redis閑談(1):構(gòu)建知識圖譜

    摘要:豐富的特性具有豐富的特性,比如可以用作分布式鎖可以持久化數(shù)據(jù)可以用作消息隊(duì)列排行榜計數(shù)器還支持通知過期等等。比如利用布隆過濾器,內(nèi)部維護(hù)一系列合法有效的,迅速判斷出請求所攜帶的是否合法有效。 showImg(https://segmentfault.com/img/remote/1460000019070847?w=750&h=300); 場景:Redis面試 showImg(http...

    ky0ncheng 評論0 收藏0
  • Redis閑談(1):構(gòu)建知識圖譜

    摘要:豐富的特性具有豐富的特性,比如可以用作分布式鎖可以持久化數(shù)據(jù)可以用作消息隊(duì)列排行榜計數(shù)器還支持通知過期等等。比如利用布隆過濾器,內(nèi)部維護(hù)一系列合法有效的,迅速判斷出請求所攜帶的是否合法有效。 showImg(https://segmentfault.com/img/remote/1460000019070847?w=750&h=300); 場景:Redis面試 showImg(http...

    starsfun 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<