1.Counting(計數)
很多情況大家都會設想純使用記憶體的方案會很有很高成本,但實際情況往往會有一些不一樣:
- COST,對于有一定吞吐需求的應用來說,肯定會單獨申請DB、Cache資源,很多擔心DB寫入性能的同學還會主動将DB更新記入異步隊列,而這三塊的資源的使用率一般都不會太高。資源算下來,你驚異的發現:反而純記憶體的方案會更精簡!
- Cache穿透風險,如果後端使用DB,肯定不會提供很高的吞吐能力,cache當機如果沒有妥善處理,那就悲劇了。
- 大多數的起始存儲需求,容量較小
諸如統計點選數等應用。由于單線程,可以避免并發問題,保證不會出錯,而且100%毫秒級性能!
指令:INCR
當然别忘記持久化,畢竟是redis隻是存了記憶體!
2.Top 10 list
産品營運總會讓你展示最近、最熱、點選率最高、活躍度最高等等條件的top list。很多更新較頻繁的清單如果使用MC+MySQL維護的話緩存失效的可能性會比較大,鑒于占用記憶體較小的情況,使用Redis做存儲也是相當不錯的。
3.Last Index
使用者最近通路記錄也是redis list的很好應用場景,lpush lpop自動過期老的登陸記錄,對于開發來說還是非常友好的。
4.Relation List/Message Queue
這裡把兩個功能放在最後,因為這兩個功能在現實問題當中遇到了一些困難,但在一定階段也确實解決了我們很多的問題,故在這裡隻做說明。
Message Queue就是通過list的lpop及lpush接口進行隊列的寫入和消費,由于本身性能較好也能解決大部分問題。
5.位操作(大資料處理)
用于資料量上億的場景下,例如幾億使用者系統的簽到,去重登入次數統計,某使用者是否線上狀态等等。
想想一下騰訊10億使用者,要幾個毫秒内查詢到某個使用者是否線上,你能怎麼做?千萬别說給每個使用者建立一個key,然後挨個記(你可以算一下需要的記憶體會很恐怖,而且這種類似的需求很多,騰訊光這個得多花多少錢。。)好吧。這裡要用到位操作——使用setbit、getbit、bitcount指令。
原理是:
redis内建構一個足夠長的數組,每個數組元素隻能是0和1兩個值,然後這個數組的下标index用來表示我們上面例子裡面的使用者id(必須是數字哈),那麼很顯然,這個幾億長的大數組就能通過下标和元素值(0和1)來建構一個記憶系統,上面我說的幾個場景也就能夠實作。用到的指令是:setbit、getbit、bitcount
6.分布式鎖與單線程機制
- 驗證前端的重複請求(可以自由擴充類似情況),可以通過redis進行過濾:每次請求将request Ip、參數、接口等hash作為key存儲redis(幂等性請求),設定多長時間有效期,然後下次請求過來的時候先在redis中檢索有沒有這個key,進而驗證是不是一定時間内過來的重複送出
- 秒殺系統,基于redis是單線程特征,防止出現資料庫“爆破”
- 全局增量ID生成,類似“秒殺”
Redis使用的重要點
1.rdb/aof Backup!
我們線上的Redis 95%以上是承擔後端存儲功能的,我們不僅用作cache,而更為一種k-v存儲,他完全替代了後端的存儲服務(MySQL),故其資料是非常重要的,如果出現資料污染和丢失,誤操作等情況,将是難以恢複的。是以備份是非常必要的!為此,我們有共享的hdfs資源作為我們的備份池,希望能随時可以還原業務所需資料。
2.Small item & Small instance!
由于Redis單線程(嚴格意義上不是單線程,但認為對request的處理是單線程的)的模型,大的資料結構list,sorted set,hash set的批量處理就意味着其他請求的等待,故使用Redis的複雜資料結構一定要控制其單key-struct的大小。
另外,Redis單執行個體的記憶體容量也應該有嚴格的限制。單執行個體記憶體容量較大後,直接帶來的問題就是故障恢複或者Rebuild從庫的時候時間較長,而更糟糕的是,Redis rewrite aof和save rdb時,将會帶來非常大且長的系統壓力,并占用額外記憶體,很可能導緻系統記憶體不足等嚴重影響性能的線上故障。我們線上96G/128G記憶體伺服器不建議單執行個體容量大于20/30G。
3.Been Available!
業界使用比較多的是Redis sentinel(哨兵)