1. 程式人生 > 程式設計 >Redis佇列,你真的需要嗎

Redis佇列,你真的需要嗎

前言

  對於多數同學來說,可能只是用過Redis的快取。但這只是其中小小的一部分,其他的例如非精準去重的計數,活躍量計算,延時佇列等都可以用redis實現。
  假設有一個業務場景,需要用到Redis的佇列,有哪些特點是需要我們關心的呢?

業務場景

問題一: 消費頻率

  假設使用Redis List作為佇列的實現,這時候需要使用while迴圈消費:

    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作為佇列時,無法確保訊息被消費者正確消費到。因此當你的業務能允許訊息的丟失時,可以嘗試著使用它。

問題三: 消費模式

  在RocketMq

或者kafka中有著消費者組和消費者的概念。

  1. 一條訊息可以被多個消費者消費:廣播模式
  2. 一條訊息只能被一個消費者消費:叢集模式
    Redis的佇列只有叢集模式。

結尾

  其實除了上述的部分,Redis作為佇列還有其他的不足之處,當然有些問題可以通過某些技巧解決,像kafka這些內部也只是佇列而已,它們能解決,我們當然也能。
  當我們在使用某種技術時,要充分考慮到這些不足之處,而不是作為面試題去考慮。