python延時佇列 站長手冊

2021-10-13 02:06:30 字數 835 閱讀 9374

kafka並沒有使用jdk自帶的timer或者delayqueue來實現延遲的功能,而是基於時間輪自定義了乙個用於實現延遲功能的定時器(systemtimer)。jdk的timer和delayqueue插入和刪除操作的平均時間複雜度為o(nlog(n)),並不能滿足kafka的高效能要求,而基於時間輪可以將插入和刪除操作的時間複雜度都降為o(1)。時間輪的應用並非kafka獨有,其應用場景還有很多,在netty、akka、quartz、zookeeper等元件中都存在時間輪的蹤影。

底層使用陣列實現,陣列中的每個元素可以存放乙個timertasklist物件。timertasklist是乙個環形雙向鍊錶,在其中的煉表項timertaskentry中封裝了真正的定時任務timertask.

kafka中到底是怎麼推進時間的呢?kafka中的定時器借助了jdk中的delayqueue來協助推進時間輪。具體做法是對於每個使用到的timertasklist都會加入到delayqueue中。kafka中的timingwheel專門用來執行插入和刪除timertaskentry的操作,而delayqueue專門負責時間推進的任務。再試想一下,delayqueue中的第乙個超時任務列表的expiration為200ms,第二個超時任務為840ms,這裡獲取delayqueue的隊頭只需要o(1)的時間複雜度。如果採用每秒定時推進,那麼獲取到第乙個超時的任務列表時執行的200次推進中有199次屬於「空推進」,而獲取到第二個超時任務時有需要執行639次「空推進」,這樣會無故空耗機器的效能資源,這裡採用delayqueue來輔助以少量空間換時間,從而做到了「精準推進」。kafka中的定時器真可謂是「知人善用」,用timingwheel做最擅長的任務新增和刪除操作,而用delayqueue做最擅長的時間推進工作,相輔相成。

Redis 延時佇列

延時佇列可以通過 redis 的 zset 有序列表 來實現。我們將訊息序列化成乙個字串作為 zset 的 value,這個訊息的到期處理時間作為 score,然後用多個執行緒輪詢 zset 獲取到期的任務進行處理,多個執行緒是為了保障可用性,萬一掛了乙個執行緒還有其它執行緒可以繼續處理。因為有多個...

mysql 延時佇列 rabbitmq 延時佇列

前言 某個產品 或者訂單,有個有效期 過了有效期要取消 方法一 寫個指令碼,用crontab 定時掃瞄 改變狀態 但是最低只能一分鐘 不適合 方法二 用swoole得毫秒定時器,每秒鐘去掃瞄表 明顯占用資源 mysql受不了 方法三 用rabbitmq延時佇列 一開始將其丟入mq 死信佇列,設定有效...

redis 佇列 redis 延時佇列

定時發公告 使用者下單30分鐘後未付款自動關閉訂單 使用者下單後延時簡訊提醒 延時關閉空閒客戶端連線 使用redis提供的有序資料結構zset,把過期時間戳作為score。public void produce string topic,string msg,date date 生產訊息 於 消費 ...