架構師之路--從業務角度談緩存的選型

  想起來幾年前挺火的前島國國民女神學霸-小島方晴子。當時替她說話的人都很慘,導師被逼自殺。她收到的壓力侮辱不是常人能夠想象的。可是她卻堅強的活着,去年還出了書。我去日本的時候,下了新幹線,前面有一羣女學生,她們看到我了,馬上彙集成一團,一邊看我一邊說悄悄話。我才發現日本人穿的衣服基本就是黑,白,灰。他們也不穿羽絨服,女孩子大冬天都是光着腿。而我穿着黃綠色的羽絨服,確實像個怪胎。爲何來以前沒人告訴我[大哭][大哭]。8年過去了,想起來還以爲尷尬。日本人是很愛背後說別人壞話的。因此我感謝我是個很普通的女孩子,並且生在中國。沒人閒的沒事去扒我以前作過的壞事。好比我好久前看不慣一個本身沒能力還勢利的混蛋,因此寫了個程序刷爆了他的郵箱。再好比我本身寫了個小程序循環註冊一個網站參加抽獎,得了好多小東西。html

  可是女孩子天生就是很堅強的,女孩子爲愛而活,其餘的什麼都扛的下。寫《傲慢與偏見》的女做家簡.奧斯汀,你們看到她寫的書的女主角們大概都能想象到做者本人是個聰明,智慧,本身漂亮且有一個更漂亮的姐姐,又很幽默的女孩。可是她卻在本身心愛的男孩子傍了個富婆以後終生未嫁,高富帥向她求婚她沒贊成。一輩子寄人籬下,與戀人死去不肯作他人婦的姐姐相依爲命,心中的痛苦又與誰人說。30多歲開始患有嚴重的憂鬱症,直到她得知本身心愛的男孩去世的消息,本身也鬱鬱而終。感恩本身運氣好,能夠快快樂樂作個普通人。mysql

  本文首發於靜兒1986的博客,原文地址是http://www.cnblogs.com/xiexj/p/6897806.htmlredis

  咱們部門併發量最大的接口服務前段時間發生了幾回業務端的流量猛增,扛不住的狀況。瓶頸在緩存上。根本性的改造正在進行中。談一談這段時間由這個問題引起的思考。算法

  首先說以前的架構確實很老了,如今直接負責這個服務的男神哥哥也很年輕,有問題是正常的。緩存選用的是樂視統一的couchbase集羣,是個memcached升級版,已經實現了持久化,本質是一個文檔型的數據庫,有人評價其性能要超過mongoDB。而後樂視網封裝了它,本身起名叫cbase,前面用moxi代理。實際上使用以爲其性能讓人擦汗。  sql

  接口服務將數據庫裏的全量視頻和專輯刷入緩存。緩存扛不住了都不會穿透DB。這裏我只想說:若是我們要是發現數據庫可能要雪崩,作熔斷,作隔離都是可取的。可是徹底不用,要它做甚[汗]. 媒資接口是一個多維度的查詢服務,緩存直接當DB用,而這個緩存的結構對數據的計算是很不利的。從數據庫裏取數據耗時通常也就是幾ms。從緩存中取數據量級並無減小,還會過量使用緩存形成cbase集羣的高負載。並且mysql是有本身的緩存的,查詢一點兒都不慢,加上索引,線上已經有的讀寫分離,其餘成熟的技術,性能也不差。業務複雜性大大增長,業務處理的CPU計算量大大增長,實際性的緩存的高速也微乎其微。數據庫

 

  話說到此,先比較一下mysql和memcached。小程序

  以前廣泛的理解是關係型數據庫自身龐大,處理過程很是耗時。可是隨着mysql的優化,解析sql語句的時間還好。通常耗時的就是讀,因爲讀寫分離的技術,也還好。重要的是控制併發線程數,也就是鏈接數在100個如下。這個我自身在一個系統沒上線的時候用線上服務器實際試驗過。QPS可承受的壓力在1w多。緩存

  來看看咱們項目,接口服務前臺11臺服務器,平均每臺QPS2k多,峯值在3k多,合起來不會超過4w。寫的主庫是單節點,壓力很小。從庫是三個節點的集羣。DBA說從庫能夠承受QPS4w(咱們用的是mariadb)。可是咱們都直接訪問memcached了。memcached集羣運維說用一個key去壓QPS可達到2.5w。實際上壓測value大小在5k的,也就幾k[狂汗],而咱們項目中超過1k的佔絕大多數。看文章說mysql5.7中使用InnoDB Memcached插件可實現QPS100w。阿里雲開發了一個AliSQL,也是mysql官方版本的一個分支,說是性能還要好。服務器

  因此,要是我,寧願不用memcached緩存,也不能不用DB啊。因此通常你們的使用方法是memcached緩存計算結果,採用最近最少使用算法或者是最不常用算法等失效策略,儘可能少的緩存。第一次去取數據的時候查詢DB,將結果緩存到memcached中。有數據更新或者刪除,就刪除memcached的相關記錄。經典用法有經典用法的設計理念。數據結構

 

 咱們的cbase集羣分配了500G內存,實際上只用到了80G。且不說在這種使用率的狀況下的哈希分佈,實際上memcache內存管理的原理是將內存分紅大大小小的片斷,

這種結構內存浪費自己就比較嚴重。若是咱們的數據大數據比較多的話,這種內存的浪費就更明顯。另外,若是數據塊比較大,大數據比較多的時候,計算哈希地址發生碰撞的概率會增長。碰撞的地址須要rehash,增長了計算時間。

  

  那將redis換成memcached會怎樣?

  Redis有一些高級功能,可是Redis是單線程,高級功能佔據CPU, I/O操做會被阻塞,因此仍是比較建議只做爲一個k/v的緩存。舉個例子,Redis不是支持有序集合嘛,若是取有序集合的必定範圍的元素,它內部使用了skiplist,關於跳錶的詳細描述請看個人另外一篇博客<看Lucene源碼必須知道的基本規則和算法>。時間複雜度是log(n),仍是須要計算的。並且因爲這個單線程,Redis在處理100K以上1M如下的大數據的時候比memcached仍是稍顯遜色的。這個1M如下是怎麼來的呢?memcached內存結構規定最大的value值只能達到1M了,而Redis可達到512M。

  Redis不只僅支持簡單的k/v類型的數據,同事還提供list,set,zset,hash等數據結構的存儲。這一點確實頗有用。

  Redis支持數據的備份,即master-slave模式的數據備份。不論是備份也好,集羣間的數據同步也好,宕機後的aof恢復也好,如今主流的解決方法使用的都是操做日誌。實現原理和mysql採用binlog的方式是同樣的。在使用的時候要注意其延時情況。

  Redis會在內存中長期存儲全部的key。但它採用數據回收機制,可以將陳舊value從內存中刪除以提供新value所必需的緩存空間。舊的數據只是內存中被刪除,磁盤上還有。不會由於回收而影響命中。因此Redis沒有最大過時時間限制。Memcached最大過時時間是一個月,不然會寫入失敗。

  據說Redis是支持身份驗證的,實際開發中沒用過這個功能。

  Redis的做者和我是一個風格的,什麼都不想用現成的。去年夏天我本身剪了一次頭髮,剪得比較成功。後來又剪了一次,慘不忍睹,可是爲了記念此次失敗,好幾個月沒換髮型。Redis的做者管理IO用的不是memcached那樣現成的libevent,而是本身封裝了一個簡單的AeEvent事件處理框架。內存管理也是同樣,本身寫了一個zmalloc.h和zmalloc.c,將內存大小存入內存塊頭部。用zmalloc代替malloc,zcalloc代替calloc,zrealloc代替realloc,zfree代替free。作C開發的就是高大上,想怎麼分配內存就怎麼分配內存。

  

  綜上所述,Redis可能能夠解決部分問題,但不是終極解決方案。由於接口服務是基於多個維度來查找的,更合適用只存儲和索引,不分詞的搜索引擎,能夠有多少內存吃多少內存,速度優點的原理和上面介紹的緩存都是同樣的。爲了更好的性能,我要實現本身的搜索引擎,具體規劃請參考個人其餘文章。

  

  感謝這半年多,一直不斷有朋友來我這邊推薦工做的,挖人的,有推薦工做兼挖人的。正好有這個平臺,問問你們最近有想動一動的麼?在北京的童鞋有想去阿里,螞蟻金服,美團點評,美團金融,貓眼電影,京東,樂視網咱們部門也在招人,還有東直門的創業公司,燕郊的創業公司。總之,均可以找我,簡歷發我郵箱 xiexiaojing@le.com。

  

  你們幫忙提提意見,是否是個人博客設計的不太好看?我一貫審美觀不太好。是否是頁首橫幅上面的照片比較醜?好吧,這個我媽要承擔50%的責任。

相關文章
相關標籤/搜索