天天看點

最大的Redis叢集:新浪Redis叢集揭秘

tape is dead,disk is tape,flash is disk,ram locality is king.       — jim gray

redis不是比較成熟的memcache或者mysql的替代品,是對于大型網際網路類應用在架構上很好的補充。現在有越來越多的應用也在紛紛基于redis做架構的改造。

可以簡單公布一下redis平台實際情況

2200+億 commands/day   5000億read/day   500億write/day

18tb+ memory

500+ servers in 6 idc    2000+instances

應該是國内外比較大的redis使用平台,今天主要從應用角度談談redis服務平台。

<a target="_blank"></a>

可以預見的是,有很多同學認為把計數全部存在記憶體中成本非常高,我在這裡用個圖表來表示下我的觀點:

最大的Redis叢集:新浪Redis叢集揭秘

mem

很多情況大家都會設想純使用記憶體的方案會很有很高成本,但實際情況往往會有一些不一樣:

1.cost,對于有一定吞吐需求的應用來說,肯定會單獨申請db、cache資源,很多擔心db寫入性能的同學還會主動将db更新記入異步隊列,而這三塊的資源的使用率一般都不會太高。資源算下來,你驚異的發現:反而純記憶體的方案會更精簡!

2.kiss原則,這對于開發是非常友好的,我隻需要建立一套連接配接池,不用擔心資料一緻性的維護,不用維護異步隊列。

3.cache穿透風險,如果後端使用db,肯定不會提供很高的吞吐能力,cache當機如果沒有妥善處理,那就悲劇了。

4.大多數的起始存儲需求,容量較小。

面對微網誌常常出現的熱點,如最近出現了較為火爆的短鍊,短時間有數以萬記的人點選、跳轉,而這裡會常常湧現一些需求,比如我們向快速在跳轉時判定使用者等級,是否有一些賬号綁定,性别愛好什麼的,已給其展示不同的内容或者資訊。

普通采用memcache+mysql的解決方案,當調用id合法的情況下,可支撐較大的吞吐。但當調用id不可控,有較多垃圾使用者調用時,由于memcache未有命中,會大量的穿透至mysql伺服器,瞬間造成連接配接數瘋長,整體吞吐量降低,響應時間變慢。

這裡我們可以用redis記錄全量的使用者判定資訊,如string key:uid int:type,做一次反向的cache,當使用者在redis快速擷取自己等級等資訊後,再去mc+mysql層去擷取全量資訊。如圖:

最大的Redis叢集:新浪Redis叢集揭秘

concept2

當然這也不是最優化的場景,如用redis做bloomfilter,可能更加省用記憶體。

産品營運總會讓你展示最近、最熱、點選率最高、活躍度最高等等條件的top list。很多更新較頻繁的清單如果使用mc+mysql維護的話緩存失效的可能性會比較大,鑒于占用記憶體較小的情況,使用redis做存儲也是相當不錯的。

使用者最近通路記錄也是redis list的很好應用場景,lpush lpop自動過期老的登陸記錄,對于開發來說還是非常友好的。

這裡把兩個功能放在最後,因為這兩個功能在現實問題當中遇到了一些困難,但在一定階段也确實解決了我們很多的問題,故在這裡隻做說明。

pinterest使用redis存儲社交graph資訊:

<a href="http://blog.gopivotal.com/case-studies-2/using-redis-at-pinterest-for-billions-of-relationships" target="_blank">http://blog.gopivotal.com/case-studies-2/using-redis-at-pinterest-for-billions-of-relationships</a>

message queue就是通過list的lpop及lpush接口進行隊列的寫入和消費,由于本身性能較好也能解決大部分問題。

redis 的lua的功能擴充實際給redis帶來了更多的應用場景,你可以編寫若幹command組合作為一個小型的非阻塞事務或者更新邏輯,如:在收到message推送時,同時1.給自己的增加一個未讀的對話 2.給自己的私信增加一個未讀消息 3.最後給發送人回執一個完成推送消息,這一層邏輯完全可以在redis server端實作。

但是,需要注意的是redis會将lua script的全部内容記錄在aof和傳送給slave,這也将是對磁盤,網卡一個不小的開銷。

很多測試和應用均已證明,

1.在性能方面redis并沒有落後memcache多少,而單線程的模型給redis反而帶來了很強的擴充性。

2.在很多場景下,redis對同一份資料的記憶體開銷是小于memcache的slab配置設定的。

3.redis提供的資料同步功能,其實是對cache的一個強有力功能擴充。 

我們線上的redis 95%以上是承擔後端存儲功能的,我們不僅用作cache,而更為一種k-v存儲,他完全替代了後端的存儲服務(mysql),故其資料是非常重要的,如果出現資料污染和丢失,誤操作等情況,将是難以恢複的。是以備份是非常必要的!為此,我們有共享的hdfs資源作為我們的備份池,希望能随時可以還原業務所需資料。

由于redis單線程(嚴格意義上不是單線程,但認為對request的處理是單線程的)的模型,大的資料結構list,sorted set,hash set的批量處理就意為着其他請求的等待,故使用redis的複雜資料結構一定要控制其單key-struct的大小。

另外,redis單執行個體的記憶體容量也應該有嚴格的限制。單執行個體記憶體容量較大後,直接帶來的問題就是故障恢複或者rebuild從庫的時候時間較長,而更糟糕的是,redis rewrite aof和save rdb時,将會帶來非常大且長的系統壓力,并占用額外記憶體,很可能導緻系統記憶體不足等嚴重影響性能的線上故障。我們線上96g/128g記憶體伺服器不建議單執行個體容量大于20/30g。

業界資料和使用比較多的是redis sentinel(哨兵)

<a href="http://www.huangz.me/en/latest/storage/redis_code_analysis/sentinel.html" target="_blank">http://www.huangz.me/en/latest/storage/redis_code_analysis/sentinel.html</a>

<a href="http://qiita.com/wellflat/items/8935016fdee25d4866d9" target="_blank">http://qiita.com/wellflat/items/8935016fdee25d4866d9</a>

2000行c實作了伺服器狀态檢測,自動故障轉移等功能。

hypnos是神話中的睡神,字面意思也是希望我們工程師無需在休息時間處理任何故障。:-)

其工作原理示意如下:

最大的Redis叢集:新浪Redis叢集揭秘

hypnos

talk is cheap, show me your code! 稍後将單獨寫篇部落格細緻講下hypnos的實作。

發現一種情況,開發在溝通後端資源設計的時候,常常因為習慣使用和錯誤了解産品定位等原因,而忽視了對真實使用使用者的評估。也許這是一份曆史資料,隻有最近一天的資料才有人進行通路,而把曆史資料的容量和最近一天請求量都抛給記憶體類的存儲現實是非常不合理的。

是以當你在究竟使用什麼樣的資料結構存儲的時候,請務必先進行成本衡量,有多少資料是需要存儲在記憶體中的?有多少資料是對使用者真正有意義的。因為這其實對後端資源的設計是至關重要的,1g的資料容量和1t的資料容量對于設計思路是完全不一樣的

全部改造線上master-slave資料同步機制,這一點我們借鑒了mysql replication的思路,使用rdb+aof+pos作為資料同步的依據,這裡簡要說明為什麼官方提供的psync沒有很好的滿足我們的需求:

假設a有兩個從庫b及c,及 a `— b&amp;c,這時我們發現master a伺服器有當機隐患需要重新開機或者a節點直接當機,需要切換b為新的主庫,如果a、b、c不共享rdb及aof資訊,c在作為b的從庫時,仍會清除自身資料,因為c節點隻記錄了和a節點的同步狀況。

故我們需要有一種将a`–b&amp;c 結構切換切換為a`–b`–c結構的同步機制,psync雖然支援斷點續傳,但仍無法支援master故障的平滑切換。

實際上 我們已經在我們定制的redis計數服務上使用了如上功能的同步,效果非常好,解決了運維負擔,但仍需向所有redis服務推廣,如果可能我們也會向官方redis提出相關sync slave的改進。

細心的同學發現我們除了使用dns作為命名系統,也在zookeeper中有一份記錄,為什麼不讓使用者直接通路一個系統,zk或者dns選擇其一呢?

其實還是很簡單,命名系統是個非常重要的元件,而dns是一套比較完善的命名系統,我們為此做了很多改進和試錯,zk的實作還是相對複雜,我們還沒有較強的把控粒度。我們也在思考用什麼做命名系統更符合我們需求。

大記憶體的使用肯定是一個重要的成本優化方向,flash盤及分布式的存儲也在我們未來計劃之中。

  原文釋出時間為:2013-10-10

本文來自雲栖社群合作夥伴“linux中國”