可以簡單公布一下Redis平台實際情況
2200+億 commands/day 5000億Read/day 500億Write/day
18TB+ Memory
500+ Servers in 6 IDC 2000+instances
應該是國內外比較大的Redis使用平台,今天主要從應用角度談談Redis服務平台。
Redis使用場景
1.Counting計數)
計數的應用在另外一篇文章裡較詳細的描述,計數場景的優化 http://www.xdata.me/?p=262 這裡就不坳述了。
可以預見的是,有很多同學認為把計數全部存在內存中成本非常高,我在這裡用個圖表來表示下我的觀點:
很多情況大家都會設想純使用內存的方案會很有很高成本,但實際情況往往會有一些不一樣:
1.COST,對於有一定吞吐需求的應用來說,肯定會單獨申請DB、Cache資源,很多擔心DB寫入性能的同學還會主動將DB更新記入異步隊列,而這三塊的資源的利用率一般都不會太高。資源算下來,你驚異的發現:反而純內存的方案會更精簡!
2.KISS原則,這對於開發是非常友好的,我只需要建立一套連接池,不用擔心數據一致性的維護,不用維護異步隊列。
3.Cache穿透風險,如果後端使用DB,肯定不會提供很高的吞吐能力,cache宕機如果沒有妥善處理,那就悲劇了。
4.大多數的起始存儲需求,容量較小。
2.Reverse cache反向cache)
面對微博常常出現的熱點,如最近出現了較為火爆的短鏈,短時間有數以萬記的人點擊、跳轉,而這裡會常常湧現一些需求,比如我們向快速在跳轉時判定用戶等級,是否有一些賬號綁定,性別愛好什麼的,已給其展示不同的內容或者信息。
普通采用Memcache+Mysql的解決方案,當調用id合法的情況下,可支撐較大的吞吐。但當調用id不可控,有較多垃圾用戶調用時,由於memcache未有命中,會大量的穿透至Mysql服務器,瞬間造成連接數瘋長,整體吞吐量降低,響應時間變慢。
這裡我們可以用redis記錄全量的用戶判定信息,如string key:uid int:type,做一次反向的cache,當用戶在redis快速獲取自己等級等信息後,再去Mc+Mysql層去獲取全量信息。如圖:
當然這也不是最優化的場景,如用Redis做bloomfilter,可能更加省用內存。
3.Top 10 list
產品運營總會讓你展示最近、最熱、點擊率最高、活躍度最高等等條件的top list。很多更新較頻繁的列表如果使用MC+MySQL維護的話緩存失效的可能性會比較大,鑒於占用內存較小的情況,使用Redis做存儲也是相當不錯的。
4.Last Index
用戶最近訪問記錄也是redis list的很好應用場景,lpush lpop自動過期老的登陸記錄,對於開發來說還是非常友好的。
5.Relation List/Message Queue
這裡把兩個功能放在最後,因為這兩個功能在現實問題當中遇到了一些困難,但在一定階段也確實解決了我們很多的問題,故在這裡只做說明。
Pinterest使用Redis存儲社交graph信息:
http://blog.gopivotal.com/case-studies-2/using-redis-at-pinterest-for-billions-of-relationships
Message Queue就是通過list的lpop及lpush接口進行隊列的寫入和消費,由於本身性能較好也能解決大部分問題。
6.Fast transaction with Lua
Redis 的Lua的功能擴展實際給Redis帶來了更多的應用場景,你可以編寫若干command組合作為一個小型的非阻塞事務或者更新邏輯,如:在收到message推送時,同時1.給自己的增加一個未讀的對話 2.給自己的私信增加一個未讀消息 3.最後給發送人回執一個完成推送消息,這一層邏輯完全可以在Redis Server端實現。
但是,需要注意的是Redis會將lua script的全部內容記錄在aof和傳送給slave,這也將是對磁盤,網卡一個不小的開銷。
7.Instead of Memcache
很多測試和應用均已證明,
1.在性能方面Redis並沒有落後Memcache多少,而單線程的模型給Redis反而帶來了很強的擴展性。
2.在很多場景下,Redis對同一份數據的內存開銷是小於Memcache的slab分配的。
3.Redis提供的數據同步功能,其實是對cache的一個強有力功能擴展。