2012·2匯總
Tumblr是世界上最流行的輕博客服務之一,2007年成立。
一,MySQL+Memcached
初期,其通知系統是由 MySQL+Memcached 的傳統架構組成。
缺點:
MySQL負擔重,表象就是 MySQL 並發事務數常常達到 InnoDB global transaction 最大值,即只能有1023個並發事務(注:特指
mysql5.0/5.1存在的問題,5.5.4以上版本修復)。
二,Tumblr 消息系統應用特性
- 按時間排序(Ordered by time)
- 唯一性,每一條消息都是唯一的(Unique (no duplicate notifications))
- 讀寫比大概是 60%/30%(Medium read/write ratio (60%/30%), mostly thanks to heavy caching)
- 每個用戶的消息條數一定(Fixed number of notifications per user)
- 數據按用戶划分,每個用戶只能讀自己的消息(Keyed by user, and read only by him/her)
三,修改后的架構:Staircar+Redis
Staircar 的輕量級HTTP服務器+ Redis 集群。
架構圖為:

四,性能指標要求
- notification request volume (over 7,500/s)
- data set size (23MM blogs, 100 notifications per blog, 160bytes per message),
- response times (<5ms)
Staircar 實際達到的指標:
在最高峰時的響應時間也在
5ms以下,其性能測試結果是能處理
每秒30,000次左右的請求。
五,引入 redis 的 presharding 思路
關鍵詞:
presharding。
缺點是,引入了運維復雜度,導致運維管理成本增加;要用好 Presharing 方案,必須有相應的自動化運維手段相配套,比如:Redis實例的啟停腳本、能檢查Redis狀態的運維監控手段。
優點是,更好的性能,更簡單的容錯,更能適應業務增長。
Presharding 思路大致的描述為:
『
假設有N台主機,每台主機上部署M個實例,整個系統有T = N × M個實例;
由於一個Redis實例的資源消耗非常小,所以一開始就可以部署比較多的 Redis 實例,比如128個實例;
在前期業務量比較低的時候,N可以比較少,M比較多,而且主機的配置(CPU+內存)可以較低;
在后期業務量較大的時候,N可以較多,M變小。
總之,通過這種方法,在容量增長過程可以始終保持Redis實例數(T)不變,所以避免了重新 Sharding 的問題。
』
拆分過程如下:
- 在新機器上啟動好對應端口的 Redis 實例。
- 配置新端口為待遷移端口的從庫。
- 待復制完成,與主庫完成同步后,切換所有客戶端配置到新的從庫的端口。
- 配置從庫為新的主庫。
- 移除老的端口實例。
- 重復上述過程遷移好所有的端口到指定服務器上。
以上拆分流程是 Redis 作者提出的一個平滑遷移的過程,不過該拆分方法還是很依賴 Redis 本身的復制功能的,如果主庫快照數據文件過大,這個復制的過程也會很久,同時會給主庫帶來壓力。所以做這個拆分的過程最好選擇為業務訪問低峰時段進行。
六,一些細節
來自於 Tumblr 開發者的一些信息:
- Machine failures:每一個 Redis 實例都有自己的 slave,這樣確保可以做 failover。
- Performance:Staircar 沒有 redis 快。但它最主要的目的是,讓 redis 基礎設施對任何客戶端都是透明的。
- Early Optimization:在一個龐大的基礎架構中,你會面對很多局部性細節,很慢的客戶端,機器宕機,其他運維問題等。我們感興趣的是在 redis 實例池之上,構建一個高性能代理。
參考資源:
1)2011,tumblr官方博客,
Staircar: Redis-powered notifications;
2)上文的
中文譯稿;
3)2011,antirez,
Redis Presharding ;
4)2011,InfoQ,
Redis復制與可擴展集群搭建,談及一種基於MySQL作為主庫,Redis作為高速數據查詢從庫的異構讀寫分離的方案:

贈圖一枚: