日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

史上最全memcached面试26题和答案

發(fā)布時(shí)間:2024/7/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 史上最全memcached面试26题和答案 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Memcached是什么,有什么作用?

Memcached是一個(gè)開源的,高性能的內(nèi)存綬存軟件,從名稱上看Mem就是內(nèi)存的意思,而Cache就是緩存的意思。Memcached的作用:通過在事先規(guī)劃好的內(nèi)存空間中臨時(shí)綬存數(shù)據(jù)庫中的各類數(shù)據(jù),以達(dá)到減少業(yè)務(wù)對數(shù)據(jù)庫的直接高并發(fā)訪問,從而達(dá)到提升數(shù)據(jù)庫的訪問性能,加速網(wǎng)站集群動(dòng)態(tài)應(yīng)用服務(wù)的能力。

?

Memcached服務(wù)在企業(yè)集群架構(gòu)中有哪些應(yīng)用場景?

一、作為數(shù)據(jù)庫的前端緩存應(yīng)用
a、完整緩存(易),靜態(tài)緩存
例如:商品分類(京東),以及商品信息,可事先放在內(nèi)存里,然后再對外提供數(shù)據(jù)訪問,這種先放到內(nèi)存,我們稱之為預(yù)熱,(先把數(shù)據(jù)存緩存中),用戶訪問時(shí)可以只讀取memcached緩存,不讀取數(shù)據(jù)庫了。
b、執(zhí)點(diǎn)緩存(難)
需要前端web程序配合,只緩存熱點(diǎn)的數(shù)據(jù),即緩存經(jīng)常被訪問的數(shù)據(jù)。
先預(yù)熱數(shù)據(jù)庫里的基礎(chǔ)數(shù)據(jù),然后在動(dòng)態(tài)更新,選讀取緩存,如果緩存里沒有對應(yīng)的數(shù)據(jù),程序再去讀取數(shù)據(jù)庫,然后程序把讀取的新數(shù)據(jù)放入緩存存儲。

特殊說明 :

1、如果碰到電商秒殺等高并發(fā)的業(yè)務(wù),一定要事先預(yù)熱,或者其它思想實(shí)現(xiàn),例如:稱殺只是獲取資格,而不是瞬間秒殺到手商品。
那么什么是獲取資格?

就是在數(shù)據(jù)庫中,把0標(biāo)成1.就有資格啦。再慢慢的去領(lǐng)取商品訂單。因?yàn)槊霘⑦^程太長會占用服務(wù)器資源。

2、如果數(shù)據(jù)更新,同時(shí)觸發(fā)緩存更新,防止給用戶過期數(shù)據(jù)。

c、對于持久化緩存存儲系統(tǒng),例如:redis,可以替代一部分?jǐn)?shù)據(jù)庫的存儲,一些簡單的數(shù)據(jù)業(yè)務(wù),投票,統(tǒng)計(jì),好友關(guān)注,商品分類等。nosql= not only sql

二、作業(yè)集群的session會話共享存儲。

3、Memcached服務(wù)在不同企業(yè)業(yè)務(wù)應(yīng)用場景中的工作流程
a、當(dāng)web程序需要訪問后端數(shù)據(jù)庫獲取數(shù)據(jù)時(shí)會優(yōu)先訪問Memcached內(nèi)存緩存,如果緩存中有數(shù)據(jù)就直接獲取返回前端服務(wù)及用戶,如果沒有數(shù)據(jù)(沒有命中),在由程序請求后端的數(shù)據(jù)庫服務(wù)器,獲取到對應(yīng)的數(shù)據(jù)后,除了返回給前端服務(wù)及用戶數(shù)據(jù)外,還會把數(shù)據(jù)放到Memcached內(nèi)存中進(jìn)行緩存,等待下次請求被訪問,Memcache內(nèi)存始終是數(shù)據(jù)庫的擋箭牌,從而大大的減輕數(shù)據(jù)庫的訪問壓力,提高整個(gè)網(wǎng)站架構(gòu)的響應(yīng)速度,提升了用戶體驗(yàn)。

b、當(dāng)程序更新,修改或刪除數(shù)據(jù)庫中已有的數(shù)據(jù)時(shí),會同時(shí)發(fā)送請求通知Memcached已經(jīng)緩存的同一個(gè)ID內(nèi)容的舊數(shù)據(jù)失效,從而保證Memcache中數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)一致。

如果在高并發(fā)場合,除了通知Memcached過程的緩存失效外,還會通過相關(guān)機(jī)制,使得在用戶訪問新數(shù)據(jù)前,通過程序預(yù)先把更新過的數(shù)據(jù)推送到memcache中緩存起來,這樣可以減少數(shù)據(jù)庫的訪問壓力,提升Memcached中緩存命中率。

c、數(shù)據(jù)庫插件可以再寫入更新數(shù)據(jù)庫后,自動(dòng)拋給MC緩存起來,自身不Cache.

?

Memcached服務(wù)分布式集群如何實(shí)現(xiàn)?

特殊說明:Memcached集群和web服務(wù)集群是不一樣的,所有Memcached的數(shù)據(jù)總和才是數(shù)據(jù)庫的數(shù)據(jù)。每臺Memcached都是部分?jǐn)?shù)據(jù)。
(一臺memcached的數(shù)據(jù),就是一部分mysql數(shù)據(jù)庫的數(shù)據(jù))

a、程序端實(shí)現(xiàn)
程序加載所有mcip列表,通過對keyhash (一致性哈希算法
例如:web1 (key)===>對應(yīng)A,B,C,D,E,F,G…..若干臺服務(wù)器。(通過哈希算法實(shí)現(xiàn))

b、負(fù)載均衡器
通過對keyhash (一致性哈希算法

一致哈希算法的目的是不但保證每個(gè)對象只請求一個(gè)對應(yīng)的服務(wù)器,而且當(dāng)節(jié)點(diǎn)宕機(jī),緩存服務(wù)器的更新重新分配比例降到最低。

Memcached服務(wù)特點(diǎn)及工作原理是什么?


a、完全基于內(nèi)存緩存的
b、節(jié)點(diǎn)之間相互獨(dú)立
cC/S模式架構(gòu),C語言編寫,總共2000行代碼。
d、異步I/O 模型,使用libevent作為事件通知機(jī)制。
e、被緩存的數(shù)據(jù)以key/value鍵值對形式存在的。
f、全部數(shù)據(jù)存放于內(nèi)存中,無持久性存儲的設(shè)計(jì),重啟服務(wù)器,內(nèi)存里的數(shù)據(jù)會丟失。
g、當(dāng)內(nèi)存中緩存的數(shù)據(jù)容量達(dá)到啟動(dòng)時(shí)設(shè)定的內(nèi)存值時(shí),就自動(dòng)使用LRU算法刪除過期的緩存數(shù)據(jù)。
h、可以對存儲的數(shù)據(jù)設(shè)置過期時(shí)間,這樣過期后的數(shù)據(jù)自動(dòng)被清除,服務(wù)本身不會監(jiān)控過期,而是在訪問的時(shí)候查看key的時(shí)間戳,判斷是否過期。
jmemcache會對設(shè)定的內(nèi)存進(jìn)行分塊,再把塊分組,然后再提供服務(wù)。

簡述Memcached內(nèi)存管理機(jī)制原理?

早期的Memcached內(nèi)存管理方式是通過malloc的分配的內(nèi)存,使用完后通過free來回收內(nèi)存,這種方式容易產(chǎn)生內(nèi)存碎片,并降低操作系統(tǒng)對內(nèi)存的管理效率。加重操作系統(tǒng)內(nèi)存管理器的負(fù)擔(dān),最壞的情況下,會導(dǎo)致操作系統(tǒng)比memcached進(jìn)程本身還慢,為了解決這個(gè)問題,Slab Allocation內(nèi)存分配機(jī)制就延生了。


現(xiàn)在Memcached利用Slab Allocation機(jī)制來分配和管理內(nèi)存。


Slab
Allocation
機(jī)制原理是按照預(yù)先規(guī)定的大小,將分配給memcached的內(nèi)存分割成特定長度的內(nèi)存塊(chunk),再把尺寸相同的內(nèi)存塊,分成組
chunks slab class),這些內(nèi)存塊不會釋放,可以重復(fù)利用。

?

而且,slab allocator還有重復(fù)使用已分配的內(nèi)存的目的。 也就是說,分配到的內(nèi)存不會釋放,而是重復(fù)利用。

Slab Allocation的主要術(shù)語

Page

分配給Slab的內(nèi)存空間,默認(rèn)是1MB。分配給Slab之后根據(jù)slab的大小切分成chunk

Chunk

用于緩存記錄的內(nèi)存空間。

Slab
Class

特定大小的chunk的組。??

集群架構(gòu)方面的問題

memcached是怎么工作的?

Memcached的神奇來自兩階段哈希(two-stage hash)。Memcached就像一個(gè)巨大的、存儲了很多 ,value>對的哈希表。通過key,可以存儲或查詢?nèi)我獾臄?shù)據(jù)。

客戶端可以把數(shù)據(jù)存儲在多臺memcached上。當(dāng)查詢數(shù)據(jù)時(shí),客戶端首先參考節(jié)點(diǎn)列表計(jì)算出key的哈希值(階段一哈希),進(jìn)而選中一個(gè)節(jié)點(diǎn);客戶端將請求發(fā)送給選中的節(jié)點(diǎn),然后memcached節(jié)點(diǎn)通過一個(gè)內(nèi)部的哈希算法(階段二哈希),查找真正的數(shù)據(jù)(item)。

memcached最大的優(yōu)勢是什么?

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

基于memcached的基本原則,可以相當(dāng)輕松地構(gòu)建出不同類型的緩存架構(gòu)。除了這篇FAQ,在其他地方很容易找到詳細(xì)資料的。

memcachedMySQLquery
cache
相比,有什么優(yōu)缺點(diǎn)?

memcached引入應(yīng)用中,還是需要不少工作量的。MySQL有個(gè)使用方便的query cache,可以自動(dòng)地緩存SQL查詢的結(jié)果,被緩存的SQL查詢可以被反復(fù)地快速執(zhí)行。Memcached與之相比,怎么樣呢?MySQLquery cache是集中式的,連接到該query cacheMySQL服務(wù)器都會受益。

* 當(dāng)您修改表時(shí),MySQLquery cache會立刻被刷新(flush)。存儲一個(gè)memcached item只需要很少的時(shí)間,但是當(dāng)寫操作很頻繁時(shí),MySQLquery cache會經(jīng)常讓所有緩存數(shù)據(jù)都失效。

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

* 在 MySQLquery cache中,我們是不能存儲任意的數(shù)據(jù)的(只能是SQL查詢結(jié)果)。而利用memcached,我們可以搭建出各種高效的緩存。比如,可以執(zhí)行多個(gè)獨(dú)立的查詢,構(gòu)建出一個(gè)用戶對象(user object),然后將用戶對象緩存到memcached中。而query cacheSQL語句級別的,不可能做到這一點(diǎn)。在小的網(wǎng)站中,query cache會有所幫助,但隨著網(wǎng)站規(guī)模的增加,query cache的弊將大于利。

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

memcached和服務(wù)器的local cache(比如PHPAPCmmap文件等)相比,有什么優(yōu)缺點(diǎn)?

首先,local cache有許多與上面(query cache)相同的問題。local cache能夠利用的內(nèi)存容量受到(單臺)服務(wù)器空閑內(nèi)存空間的限制。不過,local
cache
有一點(diǎn)比memcachedquery cache都要好,那就是它不但可以存儲任意的數(shù)據(jù),而且沒有網(wǎng)絡(luò)存取的延遲。

* local cache的數(shù)據(jù)查詢更快。考慮把highly common的數(shù)據(jù)放在local cache中吧。如果每個(gè)頁面都需要加載一些數(shù)量較少的數(shù)據(jù),考慮把它們放在local
cached
吧。

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

* local cache面臨著嚴(yán)重的內(nèi)存限制,這一點(diǎn)上面已經(jīng)提到。

memcachedcache機(jī)制是怎樣的?

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

memcached如何實(shí)現(xiàn)冗余機(jī)制?

不實(shí)現(xiàn)!我們對這個(gè)問題感到很驚訝。Memcached應(yīng)該是應(yīng)用的緩存層。它的設(shè)計(jì)本身就不帶有任何冗余機(jī)制。如果一個(gè)memcached節(jié)點(diǎn)失去了所有數(shù)據(jù),您應(yīng)該可以從數(shù)據(jù)源(比如數(shù)據(jù)庫)再次獲取到數(shù)據(jù)。您應(yīng)該特別注意,您的應(yīng)用應(yīng)該可以容忍節(jié)點(diǎn)的失效。不要寫一些糟糕的查詢代碼,寄希望于 memcached來保證一切!如果您擔(dān)心節(jié)點(diǎn)失效會大大加重?cái)?shù)據(jù)庫的負(fù)擔(dān),那么您可以采取一些辦法。比如您可以增加更多的節(jié)點(diǎn)(來減少丟失一個(gè)節(jié)點(diǎn)的影響),熱備節(jié)點(diǎn)(在其他節(jié)點(diǎn)down了的時(shí)候接管IP),等等。

memcached如何處理容錯(cuò)的?

不處理!memcached節(jié)點(diǎn)失效的情況下,集群沒有必要做任何容錯(cuò)處理。如果發(fā)生了節(jié)點(diǎn)失效,應(yīng)對的措施完全取決于用戶。節(jié)點(diǎn)失效時(shí),下面列出幾種方案供您選擇:

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

* 把失效的節(jié)點(diǎn)從節(jié)點(diǎn)列表中移除。做這個(gè)操作千萬要小心!在默認(rèn)情況下(余數(shù)式哈希算法),客戶端添加或移除節(jié)點(diǎn),會導(dǎo)致所有的緩存數(shù)據(jù)不可用!因?yàn)楣⒄盏墓?jié)點(diǎn)列表變化了,大部分key會因?yàn)楣V档母淖兌挥成涞?#xff08;與原來)不同的節(jié)點(diǎn)上。

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

* 如果希望添加和移除節(jié)點(diǎn),而不影響原先的哈希結(jié)果,可以使用一致性哈希算法(consistent hashing)。您可以百度一下一致性哈希算法。支持一致性哈希的客戶端已經(jīng)很成熟,而且被廣泛使用。去嘗試一下吧!

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

如何將memcacheditem批量導(dǎo)入導(dǎo)出?

您不應(yīng)該這樣做!Memcached是一個(gè)非阻塞的服務(wù)器。任何可能導(dǎo)致memcached暫停或瞬時(shí)拒絕服務(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ù)并不像您想象中的那么有用。不過在一個(gè)場景倒是很有用。如果您有大量的從不變化的數(shù)據(jù),并且希望緩存很快熱(warm)起來,批量導(dǎo)入緩存數(shù)據(jù)是很有幫助的。雖然這個(gè)場景并不典型,但卻經(jīng)常發(fā)生,因此我們會考慮在將來實(shí)現(xiàn)批量導(dǎo)出導(dǎo)入的功能。

如果一個(gè)memcached節(jié)點(diǎn)down了讓您很痛苦,那么您還會陷入其他很多麻煩。您的系統(tǒng)太脆弱了。您需要做一些優(yōu)化工作。比如處理驚群問題(比如 memcached節(jié)點(diǎn)都失效了,反復(fù)的查詢讓您的數(shù)據(jù)庫不堪重負(fù)這個(gè)問題在FAQ的其他提到過),或者優(yōu)化不好的查詢。記住,Memcached 并不是您逃避優(yōu)化查詢的借口。

memcached是如何做身份驗(yàn)證的?

沒有身份認(rèn)證機(jī)制!memcached是運(yùn)行在應(yīng)用下層的軟件(身份驗(yàn)證應(yīng)該是應(yīng)用上層的職責(zé))。memcached的客戶端和服務(wù)器端之所以是輕量級的,部分原因就是完全沒有實(shí)現(xiàn)身份驗(yàn)證機(jī)制。這樣,memcached可以很快地創(chuàng)建新連接,服務(wù)器端也無需任何配置。

如果您希望限制訪問,您可以使用防火墻,或者讓memcached監(jiān)聽unix domain socket

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

線程就是定律(threads rule)!在Steven GrimmFacebook的努力下,memcached 1.2及更高版本擁有了多線程模式。多線程模式允許memcached能夠充分利用多個(gè)CPU,并在CPU之間共享所有的緩存數(shù)據(jù)。memcached使用一種簡單的鎖機(jī)制來保證數(shù)據(jù)更新操作的互斥。相比在同一個(gè)物理機(jī)器上運(yùn)行多個(gè)memcached實(shí)例,這種方式能夠更有效地處理multi gets

如果您的系統(tǒng)負(fù)載并不重,也許您不需要啟用多線程工作模式。如果您在運(yùn)行一個(gè)擁有大規(guī)模硬件的、龐大的網(wǎng)站,您將會看到多線程的好處。

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

memcached能接受的key的最大長度是多少?

key的最大長度是250個(gè)字符。需要注意的是,250memcached服務(wù)器端內(nèi)部的限制,如果您使用的客戶端支持”key的前綴或類似特性,那么key(前綴+原始key)的最大長度是可以超過250個(gè)字符的。我們推薦使用使用較短的key,因?yàn)榭梢怨?jié)省內(nèi)存和帶寬。

memcached對item的過期時(shí)間有什么限制?

過期時(shí)間最大可以達(dá)到30天。memcached把傳入的過期時(shí)間(時(shí)間段)解釋成時(shí)間點(diǎn)后,一旦到了這個(gè)時(shí)間點(diǎn),memcached就把item置為失效狀態(tài)。這是一個(gè)簡單但obscure的機(jī)制。

memcached最大能存儲多大的單個(gè)item

1MB。如果你的數(shù)據(jù)大于1MB,可以考慮在客戶端壓縮或拆分到多個(gè)key中。

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

啊…這是一個(gè)大家經(jīng)常問的問題!

簡單的回答:因?yàn)閮?nèi)存分配器的算法就是這樣的。

詳細(xì)的回答:Memcached的內(nèi)存存儲引擎(引擎將來可插拔),使用slabs來管理內(nèi)存。內(nèi)存被分成大小不等的slabs chunks(先分成大小相等的slabs,然后每個(gè)slab被分成大小相等chunks,不同slabchunk大小是不相等的)。chunk的大小依次從一個(gè)最小數(shù)開始,按某個(gè)因子增長,直到達(dá)到最大的可能值。

memcached能夠更有效地使用內(nèi)存嗎?

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

什么是二進(jìn)制協(xié)議,我該關(guān)注嗎?

關(guān)于二進(jìn)制最好的信息當(dāng)然是二進(jìn)制協(xié)議規(guī)范:

二進(jìn)制協(xié)議嘗試為端提供一個(gè)更有效的、可靠的協(xié)議,減少客戶端/服務(wù)器端因處理協(xié)議而產(chǎn)生的CPU時(shí)間。

根據(jù)Facebook的測試,解析ASCII協(xié)議是memcached中消耗CPU時(shí)間最多的環(huán)節(jié)。所以,我們?yōu)槭裁床桓倪M(jìn)ASCII協(xié)議呢?

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

?

實(shí)際上,這是一個(gè)編譯時(shí)選項(xiàng)。默認(rèn)會使用內(nèi)部的slab分配器。您確實(shí)確實(shí)應(yīng)該使用內(nèi)建的slab分配器。最早的時(shí)候,memcached只使用 malloc/free來管理內(nèi)存。然而,這種方式不能與OS的內(nèi)存管理以前很好地工作。反復(fù)地malloc/free造成了內(nèi)存碎片,OS最終花費(fèi)大量的時(shí)間去查找連續(xù)的內(nèi)存塊來滿足malloc的請求,而不是運(yùn)行memcached進(jìn)程。如果您不同意,當(dāng)然可以使用malloc!只是不要在郵件列表中抱怨啊

slab分配器就是為了解決這個(gè)問題而生的。內(nèi)存被分配并劃分成chunks,一直被重復(fù)使用。因?yàn)閮?nèi)存被劃分成大小不等的slabs,如果item 的大小與被選擇存放它的slab不是很合適的話,就會浪費(fèi)一些內(nèi)存。Steven Grimm正在這方面已經(jīng)做出了有效的改進(jìn)。

memcached是原子的嗎?

所有的被發(fā)送到memcached的單個(gè)命令是完全原子的。如果您針對同一份數(shù)據(jù)同時(shí)發(fā)送了一個(gè)set命令和一個(gè)get命令,它們不會影響對方。它們將被串行化、先后執(zhí)行。即使在多線程模式,所有的命令都是原子的,除非程序有bug:)

命令序列不是原子的。如果您通過get命令獲取了一個(gè)item,修改了它,然后想把它setmemcached,我們不保證這個(gè)item沒有被其他進(jìn)程(process,未必是操作系統(tǒng)中的進(jìn)程)操作過。在并發(fā)的情況下,您也可能覆寫了一個(gè)被其他進(jìn)程setitem

memcached 1.2.5以及更高版本,提供了getscas命令,它們可以解決上面的問題。如果您使用gets命令查詢某個(gè)keyitemmemcached會給您返回該item當(dāng)前值的唯一標(biāo)識。如果您覆寫了這個(gè)item并想把它寫回到memcached中,您可以通過cas命令把那個(gè)唯一標(biāo)識一起發(fā)送給 memcached。如果該item存放在memcached中的唯一標(biāo)識與您提供的一致,您的寫操作將會成功。如果另一個(gè)進(jìn)程在這期間也修改了這個(gè) item,那么該item存放在memcached中的唯一標(biāo)識將會改變,您的寫操作就會失敗

?如何實(shí)現(xiàn)集群中的session共享存儲?

Session是運(yùn)行在一臺服務(wù)器上的,所有的訪問都會到達(dá)我們的唯一服務(wù)器上,這樣我們可以根據(jù)客戶端傳來的sessionID,來獲取session,或在對應(yīng)Session不存在的情況下(session 生命周期到了/用戶第一次登錄),創(chuàng)建一個(gè)新的Session;但是,如果我們在集群環(huán)境下,假設(shè)我們有兩臺服務(wù)器AB,用戶的請求會由Nginx服務(wù)器進(jìn)行轉(zhuǎn)發(fā)(別的方案也是同理),用戶登錄時(shí),Nginx將請求轉(zhuǎn)發(fā)至服務(wù)器A上,A創(chuàng)建了新的session,并將SessionID返回給客戶端,用戶在瀏覽其他頁面時(shí),客戶端驗(yàn)證登錄狀態(tài),Nginx將請求轉(zhuǎn)發(fā)至服務(wù)器B,由于B上并沒有對應(yīng)客戶端發(fā)來sessionIdsession,所以會重新創(chuàng)建一個(gè)新的session,并且再將這個(gè)新的sessionID返回給客戶端,這樣,我們可以想象一下,用戶每一次操作都有1/2的概率進(jìn)行再次的登錄,這樣不僅對用戶體驗(yàn)特別差,還會讓服務(wù)器上的session激增,加大服務(wù)器的運(yùn)行壓力。

為了解決集群環(huán)境下的seesion共享問題,共有4種解決方案:

1.粘性session

粘性session是指Ngnix每次都將同一用戶的所有請求轉(zhuǎn)發(fā)至同一臺服務(wù)器上,即將用戶與服務(wù)器綁定。

2.服務(wù)器session復(fù)制

即每次session發(fā)生變化時(shí),創(chuàng)建或者修改,就廣播給所有集群中的服務(wù)器,使所有的服務(wù)器上的session相同。

3.session共享

緩存session,使用redis memcached

4.session持久化

session存儲至數(shù)據(jù)庫中,像操作數(shù)據(jù)一樣才做session

memcachedredis的區(qū)別?

1、Redis不僅僅支持簡單的k/v類型的數(shù)據(jù),同時(shí)還提供listsetzsethash等數(shù)據(jù)結(jié)構(gòu)的存儲。而memcache只支持簡單數(shù)據(jù)類型,需要客戶端自己處理復(fù)雜對象

2、Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用(PS:持久化在rdbaof)。

3、由于Memcache沒有持久化機(jī)制,因此宕機(jī)所有緩存數(shù)據(jù)失效。Redis配置為持久化,宕機(jī)重啟后,將自動(dòng)加載宕機(jī)時(shí)刻的數(shù)據(jù)到緩存系統(tǒng)中。具有更好的災(zāi)備機(jī)制。

4、Memcache可以使用Magent在客戶端進(jìn)行一致性hash做分布式。Redis支持在服務(wù)器端做分布式(PS:Twemproxy/Codis/Redis-cluster多種分布式實(shí)現(xiàn)方式)

5、Memcached的簡單限制就是鍵(key)和Value的限制。最大鍵長為250個(gè)字符。可以接受的儲存數(shù)據(jù)不能超過1MB(可修改配置文件變大),因?yàn)檫@是典型slab 的最大值,不適合虛擬機(jī)使用。而RedisKey長度支持到512k

6、Redis使用的是單線程模型,保證了數(shù)據(jù)按順序提交。Memcache需要使用cas保證數(shù)據(jù)一致性。CASCheck and Set)是一個(gè)確保并發(fā)一致性的機(jī)制,屬于“樂觀鎖”范疇;原理很簡單:拿版本號,操作,對比版本號,如果一致就操作,不一致就放棄任何操作

cpu利用。由于Redis只使用單核,而Memcached可以使用多核,所以平均每一個(gè)核上Redis在存儲小數(shù)據(jù)時(shí)比Memcached性能更 高。而在100k以上的數(shù)據(jù)中,Memcached性能要高于Redis

7、memcache內(nèi)存管理:使用Slab Allocation。原理相當(dāng)簡單,預(yù)先分配一系列大小固定的組,然后根據(jù)數(shù)據(jù)大小選擇最合適的塊存儲。避免了內(nèi)存碎片。(缺點(diǎn):不能變長,浪費(fèi)了一定空間)memcached默認(rèn)情況下下一個(gè)slab的最大值為前一個(gè)的1.25倍。

8、redis內(nèi)存管理: Redis通過定義一個(gè)數(shù)組來記錄所有的內(nèi)存分配情況, Redis采用的是包裝的malloc/free,相較于Memcached的內(nèi)存 管理方法來說,要簡單很多。由于malloc 首先以鏈表的方式搜索已管理的內(nèi)存中可用的空間分配,導(dǎo)致內(nèi)存碎片比較多

你可能也喜歡:

  • 分布式緩存Redis+Memcached經(jīng)典面試題和答案
  • 2019 阿里Java 4輪面試題,含必考題答案參考!
  • 阿里螞蟻金服中間件(Java 4輪面試題含答案):Redis緩存+線程鎖+微服務(wù)等
  • 2019頭條抖音Java 3面真題,含面試題答案!
  • 2019最全BAT資深Java面試題答案合集,建議收藏~
  • 2019 最全阿里天貓Java 3面真題,含面試題答案!

  • 總結(jié)

    以上是生活随笔為你收集整理的史上最全memcached面试26题和答案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。