微博日活躍用戶1.6億+,每日訪問量達百億級,面對龐大用戶羣的海量訪問,良好的架構且不斷改進的緩存體系具備很是重要的支撐做用。本文將由新浪微博技術專家陳波老師,跟你們詳細講解那些龐大的數據都是如何呈現的。ios
本文大綱web
一、微博在運行過程當中的數據挑戰算法
二、Feed平臺系統架構後端
三、Cache架構及演進數組
四、總結與展望緩存
Feed平臺系統架構總共分爲五層,最上面是端層,好比web端、客戶端、你們用的IOS或安卓的一些客戶端,還有一些開放平臺、第三方接入的一些接口;下一層是平臺接入層,不一樣的池子,主要是爲了把好的資源集中調配給重要的核心接口,這樣遇到突發流量的時候,就有更好的彈性來服務,提升服務穩定性。再下面是平臺服務層,主要是Feed算法、關係等等。接下來是中間層,經過各類中間介質提供一些服務。最下面一層就是存儲層。服務器
一、Feed Timeline微信
你們平常刷微博的時候,好比在主站或客戶端點一下刷新,最新得到了十到十五條微博,這是怎麼構建出來的呢?網絡
刷新以後,首先會得到用戶的關注關係。好比他有一千個關注,會把這一千個ID拿到,再根據這一千個UID,拿到每一個用戶發表的一些微博。同時會獲取這個用戶的Inbox,就是他收到的特殊的一些消息,好比分組的一些微博、羣的微博、下面的關注關係、關注人的微博列表。數據結構
拿到這一系列微博列表以後進行集合、排序,拿到所須要的那些ID,再對這些ID去取每一條微博ID對應的微博內容。若是這些微博是轉發過來的,它還有一個原微博,會進一步取原微博內容。經過原微博取用戶信息,進一步根據用戶的過濾詞對這些微博進行過濾,過濾掉用戶不想看到的微博。
根據以上步驟留下的微博,會再進一步來看,用戶對這些微博有沒有收藏、點贊,作一些flag設置,還會對這些微博各類計數,轉發、評論、贊數進行組裝,最後才把這十幾條微博返回給用戶的各類端。
這樣看來,用戶一次請求獲得的十幾條記錄,後端服務器大概要對幾百甚至幾千條數據進行實時組裝,再返回給用戶,整個過程對Cache體系強度依賴,因此Cache架構設計優劣會直接影響到微博體系表現的好壞。
二、Feed Cache架構
接下來咱們看一下Cache架構,它主要分爲六層。首先第一層是Inbox,主要是分組的一些微博,而後直接對羣主的一些微博。Inbox比較少,主要是推的方式。
而後對於第二層的Outbox,每一個用戶都會發常規的微博,都會在它的Outbox裏面去。根據存的ID數量,實際上分紅多個Cache,普通的大概是200多條,若是長的大概是2000條。
第三層是一些關係,它的關注、粉絲、用戶。
第四層是內容,每一條微博一些內容存在這裏。
第五層就是一些存在性判斷,好比某條微博我有沒有贊過。以前有一些明星就說我沒有點贊這條微博怎麼顯示我點讚了,引起了一些新聞。而這種就是記錄,實際上她有在某個時候點贊過但可能忘記了。
最下面還有比較大的一層——計數,每條微博的評論、轉發等計數,還有用戶的關注數、粉絲數這些數據。
一、簡單KV數據類型
接下來咱們着重講一下微博的Cache架構演進過程。最開始微博上線時,咱們是把它做爲一個簡單的KV數據類型來存儲。咱們主要採起哈希分片存儲在MC池子裏,上線幾個月以後發現一些問題:有一些節點機器宕機或是其它緣由,大量的請求會穿透Cache層達到DB上去,致使整個請求變慢,甚至DB僵死。
因而咱們很快進行了改造,增長了一個HA層,這樣即使Main層出現某些節點宕機狀況或者掛掉以後,這些請求會進一步穿透到HA層,不會穿透到DB層。這樣能夠保證在任何狀況下,整個系統命中率不會下降,系統服務穩定性有了比較大的提高。
對於這種作法,如今業界用得比較多,而後不少人說我直接用哈希,但這裏面也有一些坑。好比我有一個節點,節點3宕機了,Main把它給摘掉,節點3的一些QA分給其餘幾個節點,這個業務量還不是很大,穿透DB,DB還能夠抗住。但若是這個節點3恢復了,它又加進來以後,節點3的訪問就會回來,稍後節點3由於網絡緣由或者機器自己的緣由,它又宕機了,一些節點3的請求又會分給其餘節點。這個時候就會出現問題,以前分散給其餘節點寫回來的數據已經沒有人更新了,若是它沒有被剔除掉就會出現混插數據。
實際上微博是一個廣場型的業務,好比突發事件,某明星找個女友,瞬間流量就30%了。突發事件後,大量的請求會出如今某一些節點,會致使這些節點很是熱,即使是MC也沒辦法知足這麼大的請求量。這時MC就會變成瓶頸,致使整個系統變慢。
基於這個緣由,咱們引入了L1層,仍是一個Main關係池,每個L1大概是Main層的N分之一,六分之1、八分之1、十分之一這樣一個內存量,根據請求量我會增長4到8個L1,這樣全部請求來了以後首先會訪問L1。L1命中的話就會直接訪問,若是沒有命中再來訪問Main-HA層,這樣在一些突發流量的時候,能夠由L1來抗住大部分熱的請求。對微博自己來講,新的數據就會越熱,只要增長不多一部份內存就會抗住更大的量。
簡單總結一下,經過簡單KV數據類型的存儲,咱們實際上以MC爲主的,層內HASH節點不漂移,Miss穿透到下一層去讀取。經過多組L1讀取性能提高,可以抗住峯值、突發流量,並且成本會大大下降。對讀寫策略,採起多寫,讀的話採用逐層穿透,若是Miss的話就進行回寫。對存在裏面的數據,咱們最初採用Json/xml,2012年以後就直接採用Protocol Buffer格式,對一些比較大的用QuickL進行壓縮。
二、集合類數據
剛纔講到簡單的QA數據,那對於複雜的集合類數據怎麼來處理?
好比我關注了2000人,新增一我的,就涉及到部分修改。有一種方式是把2000個ID所有拿下來進行修改,但這種對帶寬、機器壓力會很大。還有一些分頁獲取,我存了2000個,只須要取其中的第幾頁,好比第二頁,也就是第十到第二十個,能不能不要全量把全部數據取回去。還有一些資源的聯動計算,會計算到我關注的某些人裏面ABC也關注了用戶D。這種涉及到部分數據的修改、獲取,包括計算,對MC來講其實是不太擅長的。
各類關注關係都存在Redis裏面取,經過Hash分佈、儲存,一組多存的方式來進行讀寫分離。如今Redis的內存大概有30個T,天天都有2-3萬億的請求。
在使用Redis的過程當中,實際上仍是遇到其餘一些問題。好比從關注關係,我關注了2000個UID,有一種方式是全量存儲,但微博有大量的用戶,有些用戶登錄得比較少,有些用戶特別活躍,這樣所有放在內存裏成本開銷是比較大的。因此咱們就把Redis使用改爲Cache,好比只存活躍的用戶,若是你最近一段時間沒有活躍,會把你從Redis裏踢掉,再次有訪問的時候再把你加進來。
這時存在一個問題,由於Redis工做機制是單線程模式,若是它加某一個UV,關注2000個用戶,可能擴展到兩萬個UID,兩萬個UID塞回去基本上Redis就卡住了,沒辦法提供其餘服務。因此咱們擴展一種新的數據結構,兩萬個UID直接開了端,寫的時候直接依次把它寫到Redis裏面去,讀寫的整個效率就會很是高。它的實現是一個long型的開放數組,經過Double Hash進行尋址。
咱們對Redis進行了一些其餘的擴展,你們可能也在網上看到過咱們以前的一些分享,把數據放到公共變量裏面,整個升級過程,咱們測試1G的話加載要10分鐘,10G大概要十幾分鍾以上,如今是毫秒級升級。
對於AOF,咱們採用滾動的AOF,每一個AOF是帶一個ID的,達到必定的量再滾動到下一個AOF裏去。對RDB落地的時候,咱們會記錄構建這個RDB時,AOF文件以及它所在的位置,經過新的RDB、AOF擴展模式,實現全增量複製。
三、其餘數據類型-計數
接下來還有一些其餘的數據類型,好比一個計數,實際上計數在每一個互聯網公司均可能會遇到,對一些中小型的業務來講,實際上MC和Redis足夠用的,但在微博裏計數出現了一些特色:單條Key有多條計數,好比一條微博,有轉發數、評論數,還有點贊;一個用戶有粉絲數、關注數等各類各樣的數字。由於是計數,它的Value size是比較小的,根據它的各類業務場景,大概就是2-8個字節,通常4個字節爲多,而後每日新增的微博大概十億條記錄,總記錄就更可觀了,而後一次請求,可能幾百條計數要返回去。
四、計數器-Counter Service
最初是能夠採起Memcached,但它有個問題,若是計數超過它內容容量時,會致使一些計數的剔除,宕機或重啓後計數就沒有了。另外可能有不少計數它爲零,那這個時候怎麼存,要不要存,存的話就佔不少內存。微博天天上十億的計數,光存0都要佔大量的內存,若是不存又會致使穿透到DB裏去,對服務的可溶性會存在影響。
2010年以後咱們又採用Redis訪問,隨着數據量愈來愈大以後,發現Redis內存有效負荷仍是比較低的,它一條KV大概須要至少65個字節,但實際上咱們一個計數須要8個字節,而後Value大概4個字節,因此有效只有12個字節,還有四十多個字節都是被浪費掉的。這還只是單個KV,若是在一條Key有多個計數的狀況下,它就浪費得更多了。好比說四個計數,一個Key 8個字節,四個計數每一個計數是4個字節,16個字節大概須要26個字節就好了,可是用Redis存大概須要200多個字節。
後來咱們經過本身研發的Counter Service,內存降至Redis的五分之一到十五分之一如下,並且進行冷熱分離,熱數據存在內存裏,冷數據若是從新變熱,就把它放到LRU裏去。落地RDB、AOF,實現全增量複製,經過這種方式,熱數據單機能夠存百億級,冷數據能夠存千億級。
整個存儲架構大概是上圖這樣,上面是內存,下面是SSD,在內存裏是預先把它分紅N個Table,每一個Table根據ID的指針序列,劃出必定範圍。任何一個ID過來先找到它所在的Table,若是有直接對它增增減減,有新的計數過來,發現內存不夠的時候,就會把一個小的Table Dump到SSD裏去,留着新的位置放在最上面供新的ID來使用。
有些人疑問說,若是在某個範圍內,個人ID原本設的計數是4個字節,可是微博特別熱,超過了4個字節,變成很大的一個計數怎麼處理?對於超過限制的,咱們把它放在Aux dict進行存放,對於落在SSD裏的Table,咱們有專門的IndAux進行訪問,經過RDB方式進行復制。
五、其餘數據類型-存在性判斷
除了計數,微博還有一些業務,一些存在性判斷。好比一條微博展示的,有沒有點贊、閱讀、推薦,若是這個用戶已經讀過這個微博了,就不要再顯示給他。這種有一個很大的特色,它檢查是否存在,每條記錄很是小,好比Value1個bit就能夠了,但總數據量巨大。好比微博天天新發表微博1億左右,讀的可能有上百億、上千億這種總的數據須要判斷。怎麼來存儲是個很大的問題,並且這裏面不少存在性就是0。仍是前面說的,0要不要存?若是存了,天天就存上千億的記錄;若是不存,那大量的請求最終會穿透Cache層到DB層,任何DB都沒辦法抗住那麼大的流量。
咱們也進行了一些選型,首先直接考慮能不能用Redis。單條KV 65個字節,一個KV能夠8個字節的話,Value只有1個bit,這樣算下來每日新增內存有效率是很是低的。第二種咱們新開發的Counter Service,單條KV Value1個bit,我就存1個byt,總共9個byt就能夠了。這樣每日新增內存900G,存的話可能就只能存最新若干天的,存個三天差很少快3個T了,壓力也挺大,但比Redis已經好不少。
咱們最終方案是本身開發Phantom,先採用把共享內存分段分配,最終使用的內存只用120G就能夠。算法很簡單,對每一個Key能夠進行N次哈希,若是哈希的某一個位它是1,那麼進行3次哈希,三個數字把它設爲1。把X2也進行三次哈希,後面來判斷X1是否存在的時候,從進行三次哈希來看,若是都爲1就認爲它是存在的,若是某一個哈希X3,它的位算出來是0,那就百分百確定是不存在的。
它的實現架構比較簡單,把共享內存預先拆分到不一樣Table裏,在裏面進行開方式計算,而後讀寫,落地的話採用AOF+RDB的方式進行處理。整個過程由於放在共享內存裏面,進程要升級重啓數據也不會丟失。對外訪問的時候,建Redis協議,它直接擴展新的協議就能夠訪問咱們這個服務了。
六、小結
小結一下,到目前爲止,咱們關注了Cache集羣內的高可用、擴展性、組件高性能,還有一個特別重要就是存儲成本,還有一些咱們沒有關注到的,好比運維性如何,微博如今已經有幾千差很少上萬臺服務器等。
七、進一步優化
八、服務化
採起的方案首先就是對整個Cache進行服務化管理,對配置進行服務化管理,避免頻繁重啓,另外若是配置發生變動,直接用一個腳本修改一下。
服務化還引入Cluster Manager,實現對外部的管理,經過一個界面來進行管理,能夠進行服務校驗。服務治理方面,能夠作到擴容、縮容,SLA也能夠獲得很好的保障。另外,對於開發來講,如今就能夠屏蔽Cache資源。
最後簡單總結一下,對於微博Cache架構來講,咱們從它的數據架構、性能、儲存成本、服務化等不一樣方面進行了優化加強。
數據挑戰
Feed平臺系統架構
總共分爲五層,最上層是端層,好比web端,客戶端,你們用的ios或安卓的一些客戶端,還有一些開放平臺,第三方接入的一些接口。下面是平臺接入層,不一樣的池子,主要是爲了把好的資源集中調配給重要的核心接口,這樣突發流量的時候,有更好的彈性來服務,提升服務穩定性。再下面是平臺服務層,主要是Feed算法,關係等等。接下來是中間層,經過各類中間介質提供一些服務。最下面一層就是存儲層,平臺架構大概是這樣。
1. Feed timeline
你們平常刷微博的時候,好比在主站或客戶端點一下刷新,最新得到了十到十五條微博,它這個是怎麼構建出來的呢?刷新以後,首先會得到用戶的關注關係,好比她有一千個關注,會把這一千個ID拿到,根據這一千個UID,拿到每一個用戶發表的一些微博,同時會獲取這個用戶的Inbox,就是她收到的特殊的一些消息,好比分組的一些微博,羣的微博,下面她的關注關係,她關注人的微博列表,拿到這一系列微博列表以後進行集合、排序,拿到所須要的那些ID,再對這些ID去取每一條微博ID對應的微博內容,若是這些微博是轉發過來的,它還有一個原微博,會進一步取原微博內容,經過原微博取用戶信息,進一步根據用戶的過濾詞,對這些微博進行過濾,過濾掉用戶不想看到的微博,留下這些微博後,再進一步來看,用戶對這些微博有沒有收藏、贊,作一些flag設置,最後還會對這些微博各類計數,轉發、評論、贊數進行組裝,最後才把這十幾條微博返回給用戶的各類端。這樣看,用戶一次請求,最終獲得十幾條記錄,後端服務器大概要對幾百甚至幾千條數據進行實時組裝,再返回給用戶,整個過程對Cache體系強度依賴。因此Cache架構設計優劣直接會影響到微博體系表現的好壞。
2. Feed Cache架構
而後咱們看一下Cache架構,它主要分爲6層,首先是Inbox,主要是分組的一些微博,而後直接對羣主的一些微博,Inbox比較少,主要是推的方式。而後對於Outbox,每一個用戶都會發常規的微博,都會在它Outbox裏面去,根據存的ID的數量,實際上分紅多個Cache,普通的大概是200多,若是是長的大概是2000條。第三組就是一些關係,它的關注、粉絲、用戶。第四個就是內容,每一條微博一些內容存在這裏。下面就是一些存在性判斷,好比微博裏面,這條微博有沒有贊過,以前有一些明星就說我沒有點贊這條微博怎麼顯示我點讚了,引起一些新聞,這種就是記錄,實際上她在某個時候點贊忘記了。最下面還有比較大的一塊——計數。一條微博評論轉發等計數,對用戶來講,她的關注數粉絲數這些數據。
Cache架構及演進
1. 簡單KV數據類型
接下來咱們着重講一些微博Cache架構演進過程,最開始微博上線的時候,都是把它做爲一個簡單的KV證人數據類型來存儲,咱們主要採起哈希分片存儲在MC池子裏,上線幾個月以後發現一些問題,有一些節點機器宕機或者其它方面緣由,大量的請求會穿透Cache層達到DB上去,致使整個請求變慢,甚至DB僵死。因而咱們很快給它改造增長一個HA層,這樣即使Main層出現某些節點宕機狀況或者掛掉以後,這些請求會進一步穿透到HA層,不會穿透DB層,這樣的話能夠保證在任何狀況下,整個系統命中率不會下降,系統服務穩定性比較大提高。對於這種,如今業界用得比較多,而後不少人說我直接用哈希,但這裏面也有一些坑,好比我有一個節點,節點3它宕機了,Main把它給摘掉了,節點3的一些QA分給其餘幾個節點,這個業務量還不是很大,穿透DB,DB能夠抗住。若是後面這個節點3又恢復了,它又加進來,加進來以後,節點3的訪問又會回來,若是節點3由於網絡緣由或者機器自己的緣由,它又宕機了,一些節點3的請求又會分給其餘節點,這個時候就會出現問題,以前分散給其餘節點寫回來的數據已經沒有人更新了,若是它沒有被剔除掉就會出現混插數據。
微博和微信很大的區別,實際上微博是一個廣場型的業務,好比突發事件,某明星找個女友,瞬間流量就30%,突發事件後,大量的請求會出如今某一些節點,會致使這個節點很是熱,即使是MC也沒辦法知足這麼大的請求量。這時候整個MC就會變成瓶頸,致使整個系統變慢,基於這個緣由咱們引入L1層,仍是一個Main關係池,每個L1大概是Main層的N分之一,六分之1、八分之1、十分之一這樣一個內存量,根據請求量我會增長4到8個L1,這樣全部的請求來了以後首先會訪問L1,L1命中的話就會直接訪,若是沒有命中再來訪問Main-HA層,這樣在一些突發流量的時候,能夠由L1來抗住大部分熱的請求。對微博自己來講,新的數據就會越熱,只用增長不多一部份內存就會抗住更大的量。
簡單總結一下,經過簡單KV數據類型的存儲,咱們實際上以MC爲主的,層內HASH節點不漂移,Miss穿透到下一層去讀取。經過多組L1讀取性能提高,對峯值、突發流量可以抗住,並且成本會大大下降。對讀寫策略,採起多寫,讀的話採用逐層穿透,若是Miss的話就進行回寫,對存在裏面的數據,咱們最初採用Json/xml,12年以後就直接採用Protocol| Buffer格式,對一些比較大的用QuickL進行壓縮。
2. 集合類數據
剛纔講到簡單的QA數據,對於複雜的集合類數據怎麼來處理,好比我關注了2000人,新增一我的,這就涉及到部分修改。有一種方式把2000個ID所有拿下來進行修改,這種對帶寬、機器壓力會更大。還有一些分頁獲取,我存了2000個,只須要取其中的第幾頁,好比第二頁,也就是第十到第二十個,能不能不要全量把全部數據取回去。還有一些資源的聯動計算,會計算到我關注的某些人裏面ABC也關注了用戶D,這種涉及到部分數據的修改、獲取,包括計算,對MC來講它其實是不太擅長的。各類關注關係都存在Redis裏面取,經過Hash分佈、儲存,一組多存的方式來進行讀寫分離。如今Redis的內存大概有30個T,天天都有2-3萬億的請求。
在使用Redis的過程當中實際上仍是遇到其餘一些問題,好比從關注關係,我關注了2000個UID,有一種方式是全量存儲,但微博有大量的用戶,有些用戶登錄比較少,有些用戶特別活躍,這樣所有放在內存裏面成本開銷是比較大的。因此咱們就把Redis使用改爲Cache,好比只存活躍的用戶,若是你最近一段時間沒有活躍以後,會把你從Redis裏面踢掉,再次有訪問到你的時候把你加進來。這時候存在一個問題,Redis工做機制是單線程模式,若是它加某一個UV,關注2000個用戶,可能擴展到兩萬個UID,兩萬個UID塞回去基本上Redis就卡住了,沒辦法提供其餘服務。因此咱們擴展一種新的數據結構,兩萬個UID直接開了端,寫的時候直接依次把它寫到Redis裏面去,讀寫的整個效率就會很是高,它的實現是一個long型的開放數組,經過Double Hash進行尋址。
對Redis來講咱們進行了一些其餘的擴展,以前的一些分享,你們在網上也會看到,把數據放到公共變量裏面,整個升級過程,咱們測試1G的話加載要10分鐘,10G大概要十幾分鍾以上,如今是毫秒級升級。對於AOF,咱們採用滾動的AOF,每一個AOF是帶一個ID的,達到必定的量再滾動到下一個AOF裏面去。對RDB落地的時候,咱們會記錄構建這個RDB時,AOF文件以及它所在的位置,經過新的RDB、AOF擴展模式,實現全增量複製。
3. 其餘數據類型-計數
接下來還有一些其餘的數據類型,好比一個計數,實際上計數在每一個互聯網公司均可能會遇到,對一些中小型的業務來講,實際上MC和Redis足夠用的,但在微博裏面計數出現了一些特色,單條Key有多條計數,好比一條微博,有轉發數、評論數、還有點贊,一個用戶有粉絲數、關注數等各類各樣的數字,由於是計數,它的Value size是比較小的,根據它的各類業務場景,大概就是2-8個字節,通常4個字節爲多,而後每日新增的微博大概十億條記錄,總記錄就更可觀了,而後一次請求,可能幾百條計數要返回去。
4. 計數器-Counter Service
最初是能夠採起Memcached,但它有個問題,若是計數超過它內容容量的時候,它會致使一些計數的剔除,宕機或重啓後計數就沒有了。另外可能有不少計數它是爲零,那這個時候怎麼存,要不要存,存的話就佔不少內存。微博天天上十億的計數,光存0都要佔大量的內存,若是不存又會致使穿透到DB裏面去,對服務的可溶性就會存在影響。2010年以後咱們又採用Redis訪問,隨着數據量愈來愈大以後,發現Redis內存有效負荷仍是比較低的,它一條KV大概須要至少65個字節,但實際上咱們一個計數須要8個字節,而後Value大概4個字節,實際上有效只有12個字節,其餘還有四十多個字節都是被浪費掉的,這還只是單個KV,若是一條Key有多個計數的狀況下,它就浪費得更多了,好比說四個計數,一個Key8個字節,四個計數每一個計數是4個字節,16個字節大概須要26個字節就好了。可是用Redis存大概須要200多個字節。後來經過本身研發Counter Service,內存降至Redis的五分之一到十五分之一如下,並且進行冷熱分離,熱數據存在內存裏面,冷數據若是從新變熱,就把它放到LRU裏面去。落地RDB、AOF,實現全增量複製,經過這種方式,熱數據單機能夠存百億級,冷數據能夠存千億級。
整個存儲架構大概是這樣子,上面是內存,下面是SSD,在內存裏面是預先把它分紅N個Table,每一個Table根據ID的指針序列,劃出必定範圍,任何一個ID過來先找到它所在的Table,若是有直接對它增增減減,有新的計數過來,發現內存不夠的時候,就會把一個小的Table Dump到SSD裏面去,留着新的位置放在最上面供新的ID來使用。有些人疑問說,若是在某個範圍內,個人ID原本設的計數是4個字節,可是微博特別熱,超過了4個字節,變成很大的一個計數怎麼處理,對於超過限制的把它放在Aux dict進行存放,對於落在SSD裏面的Table,咱們有專門的IndAux進行訪問,經過RDB方式進行復制。
5. 其餘數據類型-存在性判斷
而後除了計數的話,微博還有一些業務,一些存在性判斷,好比一條微博展示的,有沒有點贊、閱讀、推薦,若是這個用戶已經讀過這個微博了,就不要再顯示給他,這種有個很大的特色,它檢查是否存在,每條記錄很是小,好比Value1個bit就能夠了,但總數據量巨大。好比微博天天新發表微博1億左右,讀的可能有上百億、上千億這種總的數據須要判斷,怎麼來存儲是個很大的問題,並且這裏面不少存在性就是0,仍是前面說的,0要不要存,若是存了,天天就存上千億的記錄,若是不存,那大量的請求最終會穿透Cache層到DB層,任何DB都沒有辦法抗住那麼大的流量。
咱們也進行了一些選型,首先直接考慮咱們能不能用Redis,單條KV65個字節,一個KV能夠8個字節的話,Value只有1個bit,這樣算下來我每日新增內存有效率是很是低的。第二種咱們新開發的Counter Service,單條KV Value1個bit,我就存1個byt,總共9個byt就能夠了,這樣每日新增內存900G,存的話可能就只能存最新若干天的,存個三天差很少快3個T了,壓力也挺大,但比Redis已經好不少。
咱們最終方案採用本身開發Phantom,先採用把共享內存分段分配,最終使用的內存只用120G就能夠,算法很簡單,對每一個Key能夠進行N次哈希,若是哈希的某一個位它是1,若是進行3次哈希,三個數字把它設爲1,把X2也進行三次哈希,後面來判斷X1是否存在的時候,進行三次哈希來看,若是都爲1就認爲它是存在的,若是某一個哈希X3,它的位算出來是0,那就百分百確定不存在的。
它的實現架構比較簡單,把共享內存預先拆分到不一樣Table裏面,在裏面進行開方式計算,而後讀寫,落地的話採用AOF+RDB的方式進行處理。整個過程由於放在共享內存裏面,進程要升級重啓數據也不會丟失。對外訪問的時候,建Redis協議,它直接擴展新的協議就能夠訪問咱們這個服務了。
6. 小結
小結一下,到目前爲止,關注Cache集羣內高可用、它的擴展性,包括它的性能,還有一個特別重要就是存儲成本,還有一些咱們沒有關注到,好比21運維性如何,微博如今已經有幾千差很少上萬臺服務器等等。
7. 進一步優化
8. 服務化
採起的方案首先就是對整個Cache進行服務化管理,對配置進行服務化管理,避免頻繁重啓,另外若是配置發生變動,直接用一個腳本修改一下。
服務化還引入Cluster Manager,實現對外部的管理,經過一個界面來進行管理,能夠進行服務校驗。服務治理方面,能夠作到擴容、縮容,SLA也能夠獲得很好保障。另外對於開發來講,如今就能夠屏蔽Cache資源。
總結與展望
最後簡單總結一下,對於微博Cache架構來講,從它數據架構、性能、儲存成本、服務化不一樣方面進行優化加強。