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