memcached+redis

傳統(tǒng)MySQL+ Memcached架構(gòu)遇到的問題

? ? ? ? 轉(zhuǎn)自 http://gnucto.blog.51cto.com/3391516/998509

  實(shí)際MySQL是適合進(jìn)行海量數(shù)據(jù)存儲(chǔ)的,通過Memcached將熱點(diǎn)數(shù)據(jù)加載到cache荷腊,加速訪問较幌,很多公司都曾經(jīng)使用過這樣的架構(gòu),但隨著業(yè)務(wù)數(shù)據(jù)量的不斷增加药蜻,和訪問量的持續(xù)增長(zhǎng),我們遇到了很多問題:

  1.MySQL需要不斷進(jìn)行拆庫(kù)拆表替饿,Memcached也需不斷跟著擴(kuò)容语泽,擴(kuò)容和維護(hù)工作占據(jù)大量開發(fā)時(shí)間。

  2.Memcached與MySQL數(shù)據(jù)庫(kù)數(shù)據(jù)一致性問題视卢。

  3.Memcached數(shù)據(jù)命中率低或down機(jī)踱卵,大量訪問直接穿透到DB,MySQL無法支撐。

  4.跨機(jī)房cache同步問題惋砂。

  眾多NoSQL百花齊放妒挎,如何選擇

  最近幾年,業(yè)界不斷涌現(xiàn)出很多各種各樣的NoSQL產(chǎn)品西饵,那么如何才能正確地使用好這些產(chǎn)品酝掩,最大化地發(fā)揮其長(zhǎng)處,是我們需要深入研究和思考的問題眷柔,實(shí)際歸根結(jié)底最重要的是了解這些產(chǎn)品的定位期虾,并且了解到每款產(chǎn)品的tradeoffs,在實(shí)際應(yīng)用中做到揚(yáng)長(zhǎng)避短驯嘱,總體上這些NoSQL主要用于解決以下幾種問題

  1.少量數(shù)據(jù)存儲(chǔ)镶苞,高速讀寫訪問。此類產(chǎn)品通過數(shù)據(jù)全部in-momery 的方式來保證高速訪問鞠评,同時(shí)提供數(shù)據(jù)落地的功能茂蚓,實(shí)際這正是Redis最主要的適用場(chǎng)景。

  2.海量數(shù)據(jù)存儲(chǔ)剃幌,分布式系統(tǒng)支持聋涨,數(shù)據(jù)一致性保證,方便的集群節(jié)點(diǎn)添加/刪除锥忿。

3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路牛郑。前者是一個(gè)完全無中心的設(shè)計(jì),節(jié)點(diǎn)之間通過gossip方式傳遞集群信息敬鬓,數(shù)據(jù)保證最終一致性淹朋,后者是一個(gè)中心化的方案設(shè)計(jì),通過類似一個(gè)分布式鎖服務(wù)來保證強(qiáng)一致性,數(shù)據(jù)寫入先寫內(nèi)存和redo log钉答,然后定期compat歸并到磁盤上础芍,將隨機(jī)寫優(yōu)化為順序?qū)懀岣邔懭胄阅堋?/p>

  4.Schema free数尿,auto-sharding等仑性。比如目前常見的一些文檔數(shù)據(jù)庫(kù)都是支持schema-free的,直接存儲(chǔ)json格式數(shù)據(jù)右蹦,并且支持auto-sharding等功能诊杆,比如mongodb。

  面對(duì)這些不同類型的NoSQL產(chǎn)品,我們需要根據(jù)我們的業(yè)務(wù)場(chǎng)景選擇最合適的產(chǎn)品何陆。

  Redis適用場(chǎng)景晨汹,如何正確的使用

  前面已經(jīng)分析過,Redis最適合所有數(shù)據(jù)in-momory的場(chǎng)景贷盲,雖然Redis也提供持久化功能淘这,但實(shí)際更多的是一個(gè)disk-backed的功能,跟傳統(tǒng)意義上的持久化有比較大的差別,那么可能大家就會(huì)有疑問铝穷,似乎Redis更像一個(gè)加強(qiáng)版的Memcached钠怯,那么何時(shí)使用Memcached,何時(shí)使用Redis呢?


如果簡(jiǎn)單地比較Redis與Memcached的區(qū)別,大多數(shù)都會(huì)得到以下觀點(diǎn):

1? Redis不僅僅支持簡(jiǎn)單的k/v類型的數(shù)據(jù)曙聂,同時(shí)還提供list晦炊,set,zset筹陵,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)刽锤。

2? Redis支持?jǐn)?shù)據(jù)的備份镊尺,即master-slave模式的數(shù)據(jù)備份朦佩。

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

拋開這些,可以深入到Redis內(nèi)部構(gòu)造去觀察更加本質(zhì)的區(qū)別弄砍,理解Redis的設(shè)計(jì)仙畦。

在Redis中,并不是所有的數(shù)據(jù)都一直存儲(chǔ)在內(nèi)存中的音婶。這是和Memcached相比一個(gè)最大的區(qū)別慨畸。Redis只會(huì)緩存所有的 key的信息,如果Redis發(fā)現(xiàn)內(nèi)存的使用量超過了某一個(gè)閥值衣式,將觸發(fā)swap的操作寸士,Redis根據(jù)“swappability = age*log(size_in_memory)”計(jì) 算出哪些key對(duì)應(yīng)的value需要swap到磁盤。然后再將這些key對(duì)應(yīng)的value持久化到磁盤中碴卧,同時(shí)在內(nèi)存中清除弱卡。這種特性使得Redis可以 保持超過其機(jī)器本身內(nèi)存大小的數(shù)據(jù)。當(dāng)然住册,機(jī)器本身的內(nèi)存必須要能夠保持所有的key婶博,畢竟這些數(shù)據(jù)是不會(huì)進(jìn)行swap操作的。同時(shí)由于Redis將內(nèi)存 中的數(shù)據(jù)swap到磁盤中的時(shí)候荧飞,提供服務(wù)的主線程和進(jìn)行swap操作的子線程會(huì)共享這部分內(nèi)存凡人,所以如果更新需要swap的數(shù)據(jù),Redis將阻塞這個(gè) 操作叹阔,直到子線程完成swap操作后才可以進(jìn)行修改挠轴。

使用Redis特有內(nèi)存模型前后的情況對(duì)比:

VM off: 300k keys, 4096 bytes values: 1.3G used

VM on:? 300k keys, 4096 bytes values: 73M used

VM off: 1 million keys, 256 bytes values: 430.12M used

VM on:? 1 million keys, 256 bytes values: 160.09M used

VM on:? 1 million keys, values as large as you want, still: 160.09M used

當(dāng) 從Redis中讀取數(shù)據(jù)的時(shí)候,如果讀取的key對(duì)應(yīng)的value不在內(nèi)存中条获,那么Redis就需要從swap文件中加載相應(yīng)數(shù)據(jù)忠荞,然后再返回給請(qǐng)求方。 這里就存在一個(gè)I/O線程池的問題。在默認(rèn)的情況下委煤,Redis會(huì)出現(xiàn)阻塞堂油,即完成所有的swap文件加載后才會(huì)相應(yīng)。這種策略在客戶端的數(shù)量較小碧绞,進(jìn)行 批量操作的時(shí)候比較合適府框。但是如果將Redis應(yīng)用在一個(gè)大型的網(wǎng)站應(yīng)用程序中,這顯然是無法滿足大并發(fā)的情況的讥邻。所以Redis運(yùn)行我們?cè)O(shè)置I/O線程 池的大小迫靖,對(duì)需要從swap文件中加載相應(yīng)數(shù)據(jù)的讀取請(qǐng)求進(jìn)行并發(fā)操作,減少阻塞的時(shí)間兴使。

如果希望在海量數(shù)據(jù)的環(huán)境中使用好Redis系宜,我相信理解Redis的內(nèi)存設(shè)計(jì)和阻塞的情況是不可缺少的。


補(bǔ)充的知識(shí)點(diǎn):

memcached和redis的比較

1 網(wǎng)絡(luò)IO模型

  Memcached是多線程发魄,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型盹牧,分為監(jiān)聽主線程和worker子線程,監(jiān)聽線程監(jiān)聽網(wǎng)絡(luò)連接励幼,接受請(qǐng)求后汰寓,將連接描述字pipe 傳遞給worker線程,進(jìn)行讀寫IO, 網(wǎng)絡(luò)層使用libevent封裝的事件庫(kù)苹粟,多線程模型可以發(fā)揮多核作用有滑,但是引入了cache coherency和鎖的問題,比如嵌削,Memcached最常用的stats 命令毛好,實(shí)際Memcached所有操作都要對(duì)這個(gè)全局變量加鎖,進(jìn)行計(jì)數(shù)等工作掷贾,帶來了性能損耗睛榄。

(Memcached網(wǎng)絡(luò)IO模型)

Redis使用單線程的IO復(fù)用模型,自己封裝了一個(gè)簡(jiǎn)單的AeEvent事件處理框架想帅,主要實(shí)現(xiàn)了epoll场靴、kqueue和select,對(duì)于單純只有IO操作來說港准,單線程可以將速度優(yōu)勢(shì)發(fā)揮到最大旨剥,但是Redis也提供了一些簡(jiǎn)單的計(jì)算功能,比如排序浅缸、聚合等轨帜,對(duì)于這些操作,單線程模型實(shí)際會(huì)嚴(yán)重影響整體吞吐量衩椒,CPU計(jì)算過程中蚌父,整個(gè)IO調(diào)度都是被阻塞住的哮兰。

2.內(nèi)存管理方面

  Memcached使用預(yù)分配的內(nèi)存池的方式,使用slab和大小不同的chunk來管理內(nèi)存苟弛,Item根據(jù)大小選擇合適的chunk存儲(chǔ)喝滞,內(nèi)存池的方式可以省去申請(qǐng)/釋放內(nèi)存的開銷,并且能減小內(nèi)存碎片產(chǎn)生膏秫,但這種方式也會(huì)帶來一定程度上的空間浪費(fèi)右遭,并且在內(nèi)存仍然有很大空間時(shí),新的數(shù)據(jù)也可能會(huì)被剔除缤削,原因可以參考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

  Redis使用現(xiàn)場(chǎng)申請(qǐng)內(nèi)存的方式來存儲(chǔ)數(shù)據(jù)窘哈,并且很少使用free-list等方式來優(yōu)化內(nèi)存分配,會(huì)在一定程度上存在內(nèi)存碎片亭敢,Redis跟據(jù)存儲(chǔ)命令參數(shù)滚婉,會(huì)把帶過期時(shí)間的數(shù)據(jù)單獨(dú)存放在一起,并把它們稱為臨時(shí)數(shù)據(jù)吨拗,非臨時(shí)數(shù)據(jù)是永遠(yuǎn)不會(huì)被剔除的满哪,即便物理內(nèi)存不夠婿斥,導(dǎo)致swap也不會(huì)剔除任何非臨時(shí)數(shù)據(jù)(但會(huì)嘗試剔除部分臨時(shí)數(shù)據(jù))劝篷,這點(diǎn)上Redis更適合作為存儲(chǔ)而不是cache。

  3.數(shù)據(jù)一致性問題

  Memcached提供了cas命令民宿,可以保證多個(gè)并發(fā)訪問操作同一份數(shù)據(jù)的一致性問題娇妓。 Redis沒有提供cas 命令,并不能保證這點(diǎn)活鹰,不過Redis提供了事務(wù)的功能哈恰,可以保證一串 命令的原子性,中間不會(huì)被任何操作打斷志群。

  4.存儲(chǔ)方式及其它方面

  Memcached基本只支持簡(jiǎn)單的key-value存儲(chǔ)着绷,不支持枚舉,不支持持久化和復(fù)制等功能

  Redis除key/value之外锌云,還支持list,set,sorted set,hash等眾多數(shù)據(jù)結(jié)構(gòu)荠医,提供了KEYS

  進(jìn)行枚舉操作,但不能在線上使用桑涎,如果需要枚舉線上數(shù)據(jù)彬向,Redis提供了工具可以直接掃描其dump文件,枚舉出所有數(shù)據(jù)攻冷,Redis還同時(shí)提供了持久化和復(fù)制等功能娃胆。

  5.關(guān)于不同語(yǔ)言的客戶端支持

  在不同語(yǔ)言的客戶端方面,Memcached和Redis都有豐富的第三方客戶端可供選擇等曼,不過因?yàn)镸emcached發(fā)展的時(shí)間更久一些里烦,目前看在客戶端支持方面凿蒜,Memcached的很多客戶端更加成熟穩(wěn)定,而Redis由于其協(xié)議本身就比Memcached復(fù)雜胁黑,加上作者不斷增加新的功能等篙程,對(duì)應(yīng)第三方客戶端跟進(jìn)速度可能會(huì)趕不上,有時(shí)可能需要自己在第三方客戶端基礎(chǔ)上做些修改才能更好的使用别厘。

  根據(jù)以上比較不難看出虱饿,當(dāng)我們不希望數(shù)據(jù)被踢出,或者需要除key/value之外的更多數(shù)據(jù)類型時(shí)触趴,或者需要落地功能時(shí)氮发,使用Redis比使用Memcached更合適。

  關(guān)于Redis的一些周邊功能

  Redis除了作為存儲(chǔ)之外還提供了一些其它方面的功能冗懦,比如聚合計(jì)算爽冕、pubsub、scripting等披蕉,對(duì)于此類功能需要了解其實(shí)現(xiàn)原理颈畸,清楚地了解到它的局限性后,才能正確的使用没讲,比如pubsub功能眯娱,這個(gè)實(shí)際是沒有任何持久化支持的,消費(fèi)方連接閃斷或重連之間過來的消息是會(huì)全部丟失的爬凑,又比如聚合計(jì)算和scripting等功能受Redis單線程模型所限徙缴,是不可能達(dá)到很高的吞吐量的,需要謹(jǐn)慎使用嘁信。

  總的來說Redis作者是一位非常勤奮的開發(fā)者于样,可以經(jīng)常看到作者在嘗試著各種不同的新鮮想法和思路潘靖,針對(duì)這些方面的功能就要求我們需要深入了解后再使用穿剖。

  總結(jié):

  1.Redis使用最佳方式是全部數(shù)據(jù)in-memory。

  2.Redis更多場(chǎng)景是作為Memcached的替代者來使用卦溢。

  3.當(dāng)需要除key/value之外的更多數(shù)據(jù)類型支持時(shí)糊余,使用Redis更合適。

  4.當(dāng)存儲(chǔ)的數(shù)據(jù)不能被剔除時(shí)既绕,使用Redis更合適啄刹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市凄贩,隨后出現(xiàn)的幾起案子誓军,更是在濱河造成了極大的恐慌,老刑警劉巖疲扎,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昵时,死亡現(xiàn)場(chǎng)離奇詭異捷雕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)壹甥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門救巷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人句柠,你說我怎么就攤上這事浦译。” “怎么了溯职?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵精盅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我谜酒,道長(zhǎng)叹俏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任僻族,我火速辦了婚禮粘驰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘述么。我一直安慰自己蝌数,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布碉输。 她就那樣靜靜地躺著籽前,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敷钾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天肄梨,我揣著相機(jī)與錄音阻荒,去河邊找鬼。 笑死众羡,一個(gè)胖子當(dāng)著我的面吹牛侨赡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播粱侣,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼羊壹,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了齐婴?” 一聲冷哼從身側(cè)響起油猫,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柠偶,沒想到半個(gè)月后情妖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睬关,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年毡证,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了电爹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡料睛,死狀恐怖丐箩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恤煞,我是刑警寧澤雏蛮,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站阱州,受9級(jí)特大地震影響挑秉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苔货,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一犀概、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夜惭,春花似錦姻灶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至敢会,卻和暖如春曾沈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸥昏。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工塞俱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吏垮。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓障涯,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親膳汪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唯蝶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359