Redis隊列,你真的須要嗎

前言

  對於多數同窗來講,可能只是用過Redis的緩存。但這只是其中小小的一部分,其餘的例如非精準去重的計數,活躍量計算,延時隊列等均可以用redis實現。
  假設有一個業務場景,須要用到Redis的隊列,有哪些特色是須要咱們關心的呢?面試

業務場景

問題一: 消費頻率

  假設使用Redis List做爲隊列的實現,這時候須要使用while循環消費:redis

while(true){
        getMessageFromList()
        sleep(time)
    }
複製代碼

  若是 time變量時間設置太小,當list中無數據時,會致使Redis qps太高。而時間設置太長,消息的延遲性就會很長。因此咱們須要設置一個合適的時間。
  上述的方法看似解決了問題,可是不夠靈活。有沒有什麼更好的辦法,可以在消息進入隊列時纔去消費呢?有想到嗎?
  Redis阻塞讀就是一個解決的方法。當隊列中沒有數據時,會產生阻塞,直到生產者發送消息到隊列。可是一直阻塞,Redis服務端通常會斷開鏈接,因此須要在客戶端捕獲Redis拋出的異常。如下是SpringBoot-Data-Redis的寫法緩存

while(true){
    System.out.println("start");
    List list = redisTemplate.executePipelined(new RedisCallback<Long>() {
        @Override
        public Long doInRedis(RedisConnection connection) throws DataAccessException {
            List l = connection.bLPop(10,"bpop4".getBytes()); // 10 表明阻塞時間
            return null;
        }
    });
    System.out.println(JSON.toJSONString(list));
}
複製代碼

問題二:數據的正確性

  在RabbitMq中,生產者發送消息到交換機中時,Exchange會有Ack機制,通知生產者已經收到消息。在消費者消費到消息時,也有ack機制通知生產者,而且生產者還能進行重試。而使用Redis做爲隊列時,沒法確保消息被消費者正確消費到。所以當你的業務能容許消息的丟失時,能夠嘗試着使用它。bash

問題三: 消費模式

  在RocketMq或者kafka中有着消費者組和消費者的概念。markdown

  1. 一條消息能夠被多個消費者消費:廣播模式
  2. 一條消息只能被一個消費者消費:集羣模式
    Redis的隊列只有集羣模式。

結尾

  其實除了上述的部分,Redis做爲隊列還有其餘的不足之處,固然有些問題能夠經過某些技巧解決,像kafka這些內部也只是隊列而已,它們能解決,咱們固然也能。
  當咱們在使用某種技術時,要充分考慮到這些不足之處,而不是做爲面試題去考慮。ide

相關文章
相關標籤/搜索