摘要:哈希的結(jié)果應(yīng)能夠保證原有已分配的內(nèi)容可以被映射到新的緩沖中去,而不會被映射到舊的緩沖集合中的其他緩沖區(qū)。平衡性平衡性是指哈希的結(jié)果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用。
memcached分布式原理與實現(xiàn)
標(biāo)簽(空格分隔): nosql
memcached是一個分布式,開源的數(shù)據(jù)存儲引擎。memcached是一款高性能的分布式內(nèi)存緩存服務(wù)器,通過減少查詢次數(shù)來抵消沉重緩慢的數(shù)據(jù)集或API調(diào)用、提高應(yīng)用響應(yīng)速度、提高可擴(kuò)展性。
在高并發(fā)的場景下, 大量的讀/寫請求涌向數(shù)據(jù)庫, 此時磁盤IO將成為瓶頸, 從而導(dǎo)致過高的響應(yīng)延遲, 因此緩存應(yīng)運而生.
Memcached的工作方式是將關(guān)鍵詞和他們對應(yīng)的值(最大能達(dá)到1MB)保存在一個關(guān)聯(lián)矩陣中(比如哈希表),延展和分布在大量的虛擬服務(wù)器中。
當(dāng)然無論是單機(jī)緩存還是分布式緩存都有其適用場景和優(yōu)缺點, 最常見的有redis和memcached. 本文主要是介紹memcached.
1.2 緩存介紹 - 計算機(jī)體系緩存硬盤 --> 內(nèi)存 --> 三級緩存 --> 二級緩存 --> 一級緩存1.3 緩存介紹 - 緩存應(yīng)用系統(tǒng)
首先訪問較快的存儲介質(zhì), 如果命中且未生效則返回內(nèi)容. 如果命中或失效則訪問較慢的存儲介質(zhì)將內(nèi)容返回同時更新緩存.
1.4 memcached特點特點 | 描述 |
---|---|
協(xié)議簡單 | 它是基于文本行的協(xié)議,直接通過telnet在memcached服務(wù)器上可進(jìn)行存取數(shù)據(jù)操作 |
基于libevent事件處理 | 異步I/O, 基于事件的單進(jìn)程和單線程, 使用libevent作為事件處理機(jī)制; |
內(nèi)置內(nèi)存存儲方式, 非持久性存儲 | 所有數(shù)據(jù)都保存在內(nèi)存中,存取數(shù)據(jù)比硬盤快,當(dāng)內(nèi)存滿后,通過LRU算法自動刪除不使用的緩存,但沒有考慮數(shù)據(jù)的容災(zāi)問題,重啟服務(wù),所有數(shù)據(jù)會丟失。 |
分布式 | 各個memcached服務(wù)器之間互不通信,各自獨立存取數(shù)據(jù),不共享任何信息。服務(wù)器并不具有分布式功能,分布式部署取決于memcache客戶端。 |
# 安裝依賴包 apt-get install libevent-dev #安裝Memcached wget http://memcached.org/latest tar -zxvf memcached-1.x.x.tar.gz cd memcached-1.x.x ./configure && make && make test && sudo make install #啟動memcached memcached -p 11211 -d -u root -P /tmp/memcached.pid
-P是表示使用TCP,默認(rèn)端口為112112.2 如何啟動-docker安裝
-d表示后臺啟動一個守護(hù)進(jìn)程(daemon)
-u表示指定root用戶啟動,默認(rèn)不能用root用戶啟動
-P表示進(jìn)程的pid存放地點,此處“p”為大寫“P”
-l,后面跟IP地址,手工指定監(jiān)聽IP地址,默認(rèn)所有IP都在監(jiān)聽
-m后面跟分配內(nèi)存大小,以MB為單位,默認(rèn)為64M
-c最大運行并發(fā)連接數(shù),默認(rèn)為1024
-f 塊大小增長因子,默認(rèn)是1.25
-M 內(nèi)存耗盡時返回錯誤,而不是刪除項,即不用LRU算法 在64位系統(tǒng)中,會報libevent-1.4.so.2文件無法找到,解決辦法是把32位目錄里的同名文件鏈接至64位目錄中,即像windows那樣建立快捷方式。 Shell > /usr/local/lib/libevent-1.4.so.2 /usr/lib64/libevent-1.4.so.2 啟動后如果發(fā)現(xiàn)沒有端口在監(jiān)聽,是因為命動命令時帶pid參數(shù)的“p”是大寫“P”,你可能寫成小寫了。
// 運行一個內(nèi)存限制為1024MB的容器: sudo docker run -name csphere-memcached -m 1024m -d -p 11211:11211 memcached:alpine
可以查看Memcached:latest 使用的 Dockerfile, 來獲取 memcached在debian下的安裝方法
2.3 如何使用分類 | 方法 | 描述 |
---|---|---|
存 | set | 添加一個新條目到memcached或是用新的數(shù)據(jù)替換替換掉已存在的條目 |
存 | add | 當(dāng)KEY不存在的情況下,它向memcached存數(shù)據(jù),否則,返回NOT_STORED響應(yīng) |
存 | replace | 當(dāng)KEY存在的情況下,它才會向memcached存數(shù)據(jù),否則返回NOT_STORED響應(yīng) |
存 | cas | 改變一個存在的KEY值 ,但它還帶了檢查的功能 |
存 | append | 在這個值后面插入新值 |
存 | prepend | 在這個值前面插入新值 |
取 | get | 取單個值 ,從緩存中返回數(shù)據(jù)時,將在第一行得到KEY的名字,flag的值和返回的value長度,真正的數(shù)據(jù)在第二行,最后返回END,如KEY不存在,第一行就直接返回END |
取 | get_multi | 一次性取多個值 |
刪 | delete |
# 清空memcache數(shù)據(jù) telnet 10.27.5.71 11211 flush_all quit //退出telnet2.4 php使用memcached
yum -y install libmemcached.x86_64 libmemcached-devel.x86_64 cd /usr/src git clone https://github.com/php-memcached-dev/php-memcached.git cd php-memcached/ git checkout php7 /alidata/server/php/bin/phpize ./configure --with-php-config=/alidata/server/php/bin/php-config make make install2.5 管理與性能監(jiān)控
可以通過命令行直接管理與監(jiān)控也可通過nagios等監(jiān)控軟件進(jìn)行監(jiān)控
命令行:
// 如果在啟動時指定了IP及端口號,這里要作相應(yīng)改動,連接成功后命令 telnet 127.0.0.1 11211
命令 | 描述 |
---|---|
stats | 統(tǒng)計memcached的各種信息 |
stats reset | 重新統(tǒng)計數(shù)據(jù) |
stats slabs | 顯示slabs信息,可以詳細(xì)看到數(shù)據(jù)的分段存儲情況 |
stats items | 顯示slab中的item數(shù)目 |
stats cachedump 1 0 | 列出slabs第一段里存的KEY值 |
set/get | 保存/獲取數(shù)據(jù) |
STAT evictions 0 | 表示要騰出新空間給新的item而移動的合法item數(shù)目 |
Memcached利用slab allocation機(jī)制來分配和管理內(nèi)存,它按照預(yù)先規(guī)定的大小,將分配的內(nèi)存分割成特定長度的內(nèi)存塊,再把尺寸相同的內(nèi)存塊分成組,數(shù)據(jù)在存放時,根據(jù)鍵值 大小去匹配slab大小,找就近的slab存放,所以存在空間浪費現(xiàn)象。
傳統(tǒng)的內(nèi)存管理方式是,使用完通過malloc分配的內(nèi)存后通過free來回收內(nèi)存,這種方式容易產(chǎn)生內(nèi)存碎片并降低操作系統(tǒng)對內(nèi)存的管理效率。
Memcached的內(nèi)存管理制效率高,而且不會造成內(nèi)存碎片,但是它最大的缺點就是會導(dǎo)致空間浪費。因為每個 Chunk都分配了特定長度的內(nèi)存空間,所以變長數(shù)據(jù)無法充分利用這些空間。如圖二所示,將100個字節(jié)的數(shù)據(jù)緩存到128個字節(jié)的Chunk中,剩余的28個字節(jié)就浪費掉了。
如何避免內(nèi)存浪費
預(yù)先計算出應(yīng)用存入的數(shù)據(jù)大小,或把同一業(yè)務(wù)類型的數(shù)據(jù)存入一個Memcached服務(wù)器中,確保存入的數(shù)據(jù)大小相對均勻,這樣就可以減少對內(nèi)存的浪費
在啟動時指定“-f"參數(shù),能在某種程度上控制內(nèi)存組之間的大小差異
在應(yīng)用中使用Memcached時,通??梢圆恢匦略O(shè)置這個參數(shù),使用默認(rèn)值1.25進(jìn)行部署
如果想優(yōu)化Memcached對內(nèi)存的使用,可以考慮重新計算數(shù)據(jù)的預(yù)期平均長度,調(diào)整這個參數(shù)來獲得合適的設(shè)置值
3.2 刪除機(jī)制(緩存策略)Memcached的緩存策略是LRU(最近最少使用)加上到期失效策略。當(dāng)你在memcached內(nèi)存儲數(shù)據(jù)項時,你有可能會指定它在緩存的失效時間,默認(rèn)為永久。當(dāng)memcached服務(wù)器用完分配的內(nèi)時,失效的數(shù)據(jù)被首先替換,然后也是最近未使用的數(shù)據(jù)。在LRU中,memcached使用的是一種Lazy Expiration策略,自己不會監(jiān)控存入的key/vlue對是否過期,而是在獲取key值時查看記錄的時間戳,檢查key/value對空間是否過期,這樣可減輕服務(wù)器的負(fù)載。
當(dāng)空間占滿時
使用LRU算法來分配空間,刪除最近最少使用的key/value對
如果不使用LRU的話, 在啟動參數(shù)上加入”-M”, 內(nèi)存耗盡時,會返回報錯信息
3.3 分布式概述memcached不相互通信,那么memcached是如何實現(xiàn)分布式的呢?
memcached的分布式實現(xiàn)主要依賴客戶端的實現(xiàn).
當(dāng)數(shù)據(jù)到達(dá)客戶端, 客戶端實現(xiàn)的算法會根據(jù)”鍵”來決定保存的memcached服務(wù)器.
服務(wù)器選定后, 命令他保存數(shù)據(jù).
取的時候也一樣, 客戶端根據(jù)”鍵”選擇服務(wù)器, 使用保存時候的相同算法就能保存選中和存的時候相同的服務(wù)器.
也就是說,存取數(shù)據(jù)分二步走,第一步,選擇服務(wù)器,第二步存取數(shù)據(jù)。
使用什么算法選擇服務(wù)器呢?
client 使用Hash算法來完成數(shù)據(jù)分散存儲.3.4 分布式算法(Hash算法)
當(dāng)向memcached集群存入/取出key/value時,memcached客戶端程序根據(jù)一定的算法計算存入哪臺服務(wù)器,然后再把key/value值存到此服務(wù)器中。也就是說,存取數(shù)據(jù)分二步走,第一步,選擇服務(wù)器,第二步存取數(shù)據(jù)。
常用的算法有兩種: 余數(shù)計算分散法 和 一致性Hash算法.
3.4.1 余數(shù)計算分散法標(biāo)準(zhǔn)的memcached分布式算法
CRC($key)%N
客戶端首先根據(jù)key來計算CPC, 然后結(jié)果對服務(wù)器取模得到memcached服務(wù)器節(jié)點
被匹配到的服務(wù)器無法連接時
rehash: 嘗試將連接的次數(shù)加到key后面, 重新hash
添加/移除服務(wù)器
余數(shù)計算分散發(fā)相當(dāng)簡單,數(shù)據(jù)分散也很優(yōu)秀
幾乎所有的緩存都會失效, 緩存重組的代價相當(dāng)?shù)拇蟆?/p>
權(quán)重不易實現(xiàn)
3.4.2 一致性hash算法將server的hash值分配至0~2^32的圓環(huán)上, 用同樣的方法求出存儲數(shù)值鍵的hash值并映射到圓上. 然后從數(shù)據(jù)映射到的位置開始順時針查找, 將數(shù)據(jù)存放至找到的第一臺服務(wù)器上. 如果超過0~2^32還找不到, 則將數(shù)據(jù)存放至第一臺服務(wù)器.
如果新添/刪除一臺server, 在一致性hash算法下會有什么影響?
如圖, 新添/刪除server時, 只在圓上增加服務(wù)器的逆時針方向的第一臺服務(wù)器上的鍵會受到影響。
優(yōu)化一致性hash算法
一般的一致性hash算法最大限度的抑制了鍵的重新分配, 并且有的實現(xiàn)方式還采用了虛擬節(jié)點的思想
服務(wù)器的映射地點的分布非常的不均勻, 導(dǎo)致數(shù)據(jù)訪問傾斜, 大量的key被映射到同一臺服務(wù)器上.
虛擬節(jié)點: 每臺機(jī)器計算出多個hash值, 每個值對應(yīng)環(huán)上的一個節(jié)點位置
key的映射方式不變, 就多了層從虛擬節(jié)點到再映射到物理機(jī)的過程
優(yōu)化后: 在物理機(jī)很少的情況下, 只要虛擬節(jié)點足夠多, 也能使的key分布相對均勻. 提升了算法的平衡性.
單調(diào)性是指如果已經(jīng)有一些內(nèi)容通過哈希分派到了相應(yīng)的緩沖中,又有新的緩沖加入到系統(tǒng)中。哈希的結(jié)果應(yīng)能夠保證原有已分配的內(nèi)容可以被映射到新的緩沖中去,而不會被映射到舊的緩沖集合中的其他緩沖區(qū)。
平衡性是指哈希的結(jié)果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用。
hash 算法并不是保證絕對的平衡0x04 常見問題 4.1 memcached與redis的區(qū)別?
對比點 | memcached | redis |
---|---|---|
數(shù)據(jù)結(jié)構(gòu) | 單一(存儲數(shù)據(jù)的類型都是String字符串類型) | 豐富(String、List、Set、Sortedset、Hash) |
內(nèi)存使用率 | 使用簡單的key-value存儲,Memcached的內(nèi)存利用率更高 | Redis采用hash結(jié)構(gòu)來做key-value存儲,由于其組合式的壓縮,其內(nèi)存利用率會高于Memcached |
持久化 | 不可以 | 可以(可以把數(shù)據(jù)隨時存儲在磁盤上) |
數(shù)據(jù)同步 | 不可以 | 可以 |
多核 | 可以使用多核(多線程) | 單核 |
數(shù)據(jù)大小 | 單個key(變量)存放的數(shù)據(jù)有1M的限制 | 單個key(變量)存放的數(shù)據(jù)有1GB的限制 |
計算能力 | 無 | 本身有一定的計算功能 |
Redis在存儲小數(shù)據(jù)時比Memcached性能更高
在100k以上的數(shù)據(jù)中,Memcached性能要高于Redis
memcached增加了網(wǎng)絡(luò)IO的次數(shù)和數(shù)據(jù)體積
memcached和redis對過期數(shù)據(jù)的處理
Redis是懶處理,對有有效期的數(shù)據(jù)會做有效期的標(biāo)識,在指定時間會對有過期時間的數(shù)據(jù)做處理。隨機(jī)取出一部分?jǐn)?shù)據(jù),檢查是否有過期數(shù)據(jù),如果過期數(shù)據(jù)超過25/100,則反復(fù)此過程
4.2 memcache為什么快?它使用libevent,可以應(yīng)付任意數(shù)量打開的連接(使用epoll,而非poll),使用非阻塞網(wǎng)絡(luò)IO,分布式散列對象到不同的服務(wù)器,查詢復(fù)雜度是O(1)。
4.3 Memcache緩存命中率?緩存命中率 = get_hits/cmd_get * 100%
4.4 Memcache集群實現(xiàn)一致性Hash
0x05 總結(jié)a. 在軟件工程的項目實戰(zhàn)中, 經(jīng)常會遇到時間/空間的權(quán)衡, 緩存是權(quán)衡中被研究出的一種典型的技術(shù), 而memcached又是此類技術(shù)中的佼佼者.
b. 在高并發(fā)環(huán)境下,大量的讀、寫請求涌向數(shù)據(jù)庫,此時磁盤IO將成為瓶頸,從而導(dǎo)致過高的響應(yīng)延遲,因此緩存應(yīng)運而生。
c. 本文在理解緩存基本概念的情況下介紹了memcached的分布式算法實現(xiàn)原理
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/61728.html
摘要:哈希的結(jié)果應(yīng)能夠保證原有已分配的內(nèi)容可以被映射到新的緩沖中去,而不會被映射到舊的緩沖集合中的其他緩沖區(qū)。平衡性平衡性是指哈希的結(jié)果能夠盡可能分布到所有的緩沖中去,這樣可以使得所有的緩沖空間都得到利用。 memcached分布式原理與實現(xiàn) 標(biāo)簽(空格分隔): nosql 0x01 概況 1.1 什么是memcached memcached是一個分布式,開源的數(shù)據(jù)存儲引擎。memcach...
摘要:啟動時可以指定監(jiān)聽的服務(wù)器的內(nèi)網(wǎng)外網(wǎng)端口號所以做分布式測試時,一臺服務(wù)器上可以啟動多個不同端口號的進(jìn)程使用的內(nèi)存大小等關(guān)鍵參數(shù)。分布式實現(xiàn)原理的目前版本是通過實現(xiàn),采用了單進(jìn)程單線程異步,基于事件的服務(wù)方式使用作為事件通知實現(xiàn)。 1、什么是MemCache 官方說明: MemCache是一個自由、源碼開放、高性能、分布式的分布式內(nèi)存對象緩存系統(tǒng),用于動態(tài)Web應(yīng)用以減輕數(shù)據(jù)庫的負(fù)載。它...
摘要:啟動時可以指定監(jiān)聽的服務(wù)器的內(nèi)網(wǎng)外網(wǎng)端口號所以做分布式測試時,一臺服務(wù)器上可以啟動多個不同端口號的進(jìn)程使用的內(nèi)存大小等關(guān)鍵參數(shù)。分布式實現(xiàn)原理的目前版本是通過實現(xiàn),采用了單進(jìn)程單線程異步,基于事件的服務(wù)方式使用作為事件通知實現(xiàn)。 1、什么是MemCache 官方說明: MemCache是一個自由、源碼開放、高性能、分布式的分布式內(nèi)存對象緩存系統(tǒng),用于動態(tài)Web應(yīng)用以減輕數(shù)據(jù)庫的負(fù)載。它...
摘要:當(dāng)重啟時,將會讀取文件進(jìn)行重放以恢復(fù)到關(guān)閉前的最后時刻。伸縮性受到線程數(shù)的限制,線程數(shù)的調(diào)度對也是不小的負(fù)擔(dān)。所以允許我們設(shè)置線程池的大小,對需要從文件中加載相應(yīng)數(shù)據(jù)的讀取請求進(jìn)行并發(fā)操作,減少阻塞的時間。 存儲原理(持久化) Mongo Mongo的數(shù)據(jù)將會保存在底層文件系統(tǒng),因此存儲容量遠(yuǎn)大于redis和memcached。一個database中所有的collections以及索...
閱讀 1616·2021-11-23 09:51
閱讀 1185·2019-08-30 13:57
閱讀 2268·2019-08-29 13:12
閱讀 2020·2019-08-26 13:57
閱讀 1205·2019-08-26 11:32
閱讀 983·2019-08-23 15:08
閱讀 710·2019-08-23 14:42
閱讀 3091·2019-08-23 11:41