国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

Redis 延時隊列,一次性搞明白

數(shù)據(jù)分析與開發(fā) ? 來源:數(shù)據(jù)分析與開發(fā) ? 作者:數(shù)據(jù)分析與開發(fā) ? 2020-10-30 16:34 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

所謂延時隊列就是延時的消息隊列,下面說一下一些業(yè)務場景

實踐場景

訂單支付失敗,每隔一段時間提醒用戶

用戶并發(fā)量的情況,可以延時2分鐘給用戶發(fā)短信

先來看看Redis實現(xiàn)普通的消息隊列

我們知道,對于專業(yè)的消息隊列中間件,如Kafka和RabbitMQ,消費者在消費消息之前要進行一系列的繁瑣過程。

如RabbitMQ發(fā)消息之前要創(chuàng)建 Exchange,再創(chuàng)建 Queue,還要將 Queue 和 Exchange 通過某種規(guī)則綁定起來,發(fā)消息的時候要指定 routingkey,還要控制頭部信息

但是絕大 多數(shù)情況下,雖然我們的消息隊列只有一組消費者,但還是需要經(jīng)歷上面一些過程。

有了 Redis,對于那些只有一組消費者的消息隊列,使用 Redis 就可以非常輕松的搞定。Redis 的消息隊列不是專業(yè)的消息隊列,它沒有非常多的高級特性, 沒有 ack 保證,如果對消息的可靠性有著極致的追求,那么它就不適合使用

異步消息隊列基本實現(xiàn)

Redis 的 list(列表) 數(shù)據(jù)結構常用來作為異步消息隊列使用,使用 rpush/lpush 操作入隊列, 使用 lpop 和 rpop 來出隊列

>rpushqueue月伴飛魚1月伴飛魚2月伴飛魚3 (integer)3 >lpopqueue "月伴飛魚1" >llenqueue (integer)2

問題1:如果隊列空了

客戶端是通過隊列的 pop 操作來獲取消息,然后進行處理。處理完了再接著獲取消息, 再進行處理。如此循環(huán)往復,這便是作為隊列消費者的客戶端的生命周期。

可是如果隊列空了,客戶端就會陷入 pop 的死循環(huán),不停地 pop,沒有數(shù)據(jù),接著再 pop, 又沒有數(shù)據(jù)。這就是浪費生命的空輪詢。空輪詢不但拉高了客戶端的 CPU,redis 的 QPS 也 會被拉高,如果這樣空輪詢的客戶端有幾十來個,Redis 的慢查詢可能會顯著增多。

通常我們使用 sleep 來解決這個問題,讓線程睡一會,睡個 1s 鐘就可以了。不但客戶端 的 CPU 能降下來,Redis 的 QPS 也降下來了

問題2:隊列延遲

用上面睡眠的辦法可以解決問題。同時如果只有 1 個消費者,那么這個延遲就是 1s。如果有多個消費者,這個延遲會有所下降,因 為每個消費者的睡覺時間是岔開來的。

有沒有什么辦法能顯著降低延遲呢?

那就是 blpop/brpop。

這兩個指令的前綴字符 b 代表的是 blocking,也就是阻塞讀。

阻塞讀在隊列沒有數(shù)據(jù)的時候,會立即進入休眠狀態(tài),一旦數(shù)據(jù)到來,則立刻醒過來。消 息的延遲幾乎為零。用 blpop/brpop 替代前面的 lpop/rpop,就完美解決了上面的問題。

問題3:空閑連接自動斷開

其實他還有個問題需要解決—— 空閑連接的問題。

如果線程一直阻塞在哪里,Redis 的客戶端連接就成了閑置連接,閑置過久,服務器一般 會主動斷開連接,減少閑置資源占用。這個時候 blpop/brpop 會拋出異常來。

所以編寫客戶端消費者的時候要小心,注意捕獲異常,還要重試。

分布式鎖沖突處理

假如客戶端在處理請求時加分布式鎖沒加成功怎么辦。

一般有 3 種策略來處理加鎖失?。?/p>

1、直接拋出異常,通知用戶稍后重試;

2、sleep 一會再重試;

3、將請求轉移至延時隊列,過一會再試;

直接拋出特定類型的異常

這種方式比較適合由用戶直接發(fā)起的請求,用戶看到錯誤對話框后,會先閱讀對話框的內(nèi) 容,再點擊重試,這樣就可以起到人工延時的效果。如果考慮到用戶體驗,可以由前端的代碼 替代用戶自己來進行延時重試控制。它本質上是對當前請求的放棄,由用戶決定是否重新發(fā)起 新的請求。

sleep

sleep 會阻塞當前的消息處理線程,會導致隊列的后續(xù)消息處理出現(xiàn)延遲。如果碰撞的比 較頻繁或者隊列里消息比較多,sleep 可能并不合適。如果因為個別死鎖的 key 導致加鎖不成 功,線程會徹底堵死,導致后續(xù)消息永遠得不到及時處理。

延時隊列

這種方式比較適合異步消息處理,將當前沖突的請求扔到另一個隊列延后處理以避開沖突。

延時隊列的實現(xiàn)

我們可以使用 zset這個命令,用設置好的時間戳作為score進行排序,使用zadd score1 value1 ....命令就可以一直往內(nèi)存中生產(chǎn)消息。再利用 zrangebysocre 查詢符合條件的所有待處理的任務,通過循環(huán)執(zhí)行隊列任務即可。也可以通過zrangebyscore key min max withscores limit 0 1查詢最早的一條任務,來進行消費

privateJedisjedis; publicvoidredisDelayQueueTest(){ Stringkey="delay_queue"; //實際開發(fā)建議使用業(yè)務ID和隨機生成的唯一ID作為value,隨機生成的唯一ID可以保證消息的唯一性,業(yè)務ID可以避免value攜帶的信息過多 StringorderId1=UUID.randomUUID().toString(); jedis.zadd(queueKey,System.currentTimeMillis()+5000,orderId1); StringorderId12=UUID.randomUUID().toString(); jedis.zadd(queueKey,System.currentTimeMillis()+5000,orderId2); newThread(){ @Override publicvoidrun(){ while(true){ SetresultList; //只獲取第一條數(shù)據(jù),只獲取不會移除數(shù)據(jù) resultList=jedis.zrangebyscore(key,System.currentTimeMillis(),0,1); if(resultList.size()==0){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); break; } }else{ //移除數(shù)據(jù)獲取到的數(shù)據(jù) if(jedis.zrem(key,resultList.get(0))>0){ StringorderId=resultList.get(0); log.info("orderId={}",resultList.get(0)); this.handleMsg(orderId); } } } } }.start(); } publicvoidhandleMsg(Tmsg){ System.out.println(msg); }

上面的實現(xiàn), 在多線程邏輯上也是沒有問題的, 假設有兩個線程 T1, T2和其他更多線程, 處理邏輯如下, 保證了多線程情況下只有一個線程處理了對應的消息:

1.T1, T2 和其他更多線程調用 zrangebyscore 獲取到了一條消息 A

2.T1 準備開始刪除消息 A, 由于是原子操作, T2 和其他更多線程等待 T1 執(zhí)行 zrem 刪除消息 A 后再執(zhí)行 zrem 刪除消息 A

3.T1 刪除了消息 A, 返回刪除成功標記 1, 并對消息 A 進行處理

4.T2 其他更多線程開始 zrem 刪除消息 A, 由于消息 A 已經(jīng)被刪除, 所以所有的刪除均失敗, 放棄了對消息 A 的處理

同時,我們要注意一定要對handle_msg進行異常捕獲,避免因為個別任務處理問題導致循環(huán)異常退 出

進一步優(yōu)化

上面的算法中同一個任務可能會被多個進程取到之后再使用 zrem 進行爭搶,那些沒搶到 的進程都是白取了一次任務,這是浪費??梢钥紤]使用 lua scripting 來優(yōu)化一下這個邏輯,將 zrangebyscore 和 zrem 一同挪到服務器端進行原子化操作,這樣多個進程之間爭搶任務時就不 會出現(xiàn)這種浪費了

使用調用Lua腳本進一步優(yōu)化

Lua 腳本, 如果有超時的消息, 就刪除, 并返回這條消息, 否則返回空字符串:

StringluaScript="localresultArray=redis.call('zrangebyscore',KEYS[1],0,ARGV[1],'limit',0,1) "+ "if#resultArray>0then "+ "ifredis.call('zrem',KEYS[1],resultArray[1])>0then "+ "returnresultArray[1] "+ "else "+ "return'' "+ "end "+ "else "+ "return'' "+ "end"; jedis.eval(luaScript,ScriptOutputType.VALUE,newString[]{key},String.valueOf(System.currentTimeMillis()));

Redis延時隊列優(yōu)勢

Redis用來進行實現(xiàn)延時隊列是具有這些優(yōu)勢的:

1.Redis zset支持高性能的 score 排序。

2.Redis是在內(nèi)存上進行操作的,速度非??臁?/p>

3.Redis可以搭建集群,當消息很多時候,我們可以用集群來提高消息處理的速度,提高可用性。

4.Redis具有持久化機制,當出現(xiàn)故障的時候,可以通過AOF和RDB方式來對數(shù)據(jù)進行恢復,保證了數(shù)據(jù)的可靠性

Redis延時隊列劣勢

使用 Redis 實現(xiàn)的延時消息隊列也存在數(shù)據(jù)持久化, 消息可靠性的問題

沒有重試機制 - 處理消息出現(xiàn)異常沒有重試機制, 這些需要自己去實現(xiàn), 包括重試次數(shù)的實現(xiàn)等

沒有 ACK 機制 - 例如在獲取消息并已經(jīng)刪除了消息情況下, 正在處理消息的時候客戶端崩潰了, 這條正在處理的這些消息就會丟失, MQ 是需要明確的返回一個值給 MQ 才會認為這個消息是被正確的消費了

如果對消息可靠性要求較高, 推薦使用 MQ 來實現(xiàn)

Redission實現(xiàn)延時隊列

基于Redis的Redisson分布式延遲隊列結構的RDelayedQueue Java對象在實現(xiàn)了RQueue接口的基礎上提供了向隊列按要求延遲添加項目的功能。該功能可以用來實現(xiàn)消息傳送延遲按幾何增長或幾何衰減的發(fā)送策略

RQueuedistinationQueue=... RDelayedQueuedelayedQueue=getDelayedQueue(distinationQueue); //10秒鐘以后將消息發(fā)送到指定隊列 delayedQueue.offer("msg1",10,TimeUnit.SECONDS); //一分鐘以后將消息發(fā)送到指定隊列 delayedQueue.offer("msg2",1,TimeUnit.MINUTES);

在該對象不再需要的情況下,應該主動銷毀。僅在相關的Redisson對象也需要關閉的時候可以不用主動銷毀。

RDelayedQueuedelayedQueue=... delayedQueue.destroy();

是不是很方便...............

責任編輯:xj

原文標題:Redis 延時隊列,這次徹底給你整明白了

文章出處:【微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關注!文章轉載請注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編程
    +關注

    關注

    90

    文章

    3716

    瀏覽量

    97185
  • 線程
    +關注

    關注

    0

    文章

    509

    瀏覽量

    20826
  • Redis
    +關注

    關注

    0

    文章

    392

    瀏覽量

    12185

原文標題:Redis 延時隊列,這次徹底給你整明白了

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    智能手環(huán)做 FCC ID 認證要哪些資料?一次性準備清單

    上取決于資料準備是否完整、規(guī)范。本文從企業(yè)實操角度,系統(tǒng)整理智能手環(huán)申請 FCC ID 認證所需的全部資料清單,幫助你一次性準備到位。
    的頭像 發(fā)表于 02-05 16:08 ?131次閱讀
    智能手環(huán)做 FCC ID 認證要哪些資料?<b class='flag-5'>一次性</b>準備清單

    一次寫入,永久鎖定!OTP存儲操作需謹慎

    今天,我們起來聊聊LuatOS中的OTP功能。 OTP(One-Time Programmable Memory) 是一次性可編程存儲。其核心特點是 “一次寫入,永久鎖定” ,數(shù)據(jù)在物理層
    的頭像 發(fā)表于 01-27 17:52 ?1046次閱讀
    <b class='flag-5'>一次</b>寫入,永久鎖定!OTP存儲操作需謹慎

    與軸一次成型的微電機轉子磁鐵

    在微型電機領域,與軸一次成型的轉子磁鐵正逐漸成為種被廣泛采用的結構方案,相比傳統(tǒng)“磁鐵+轉軸后裝配”的形式,這類轉子在結構、性能和一致性方面都有明顯優(yōu)勢,特別適合對體積、精度和可靠性要求較高的微電機應用。
    的頭像 發(fā)表于 01-27 11:40 ?332次閱讀
    與軸<b class='flag-5'>一次</b>成型的微電機轉子磁鐵

    光伏一次調頻設備/一次調頻裝置|光伏一次調頻涉網(wǎng)試驗/光伏電站一次調頻建設改造方案

    2025年以來能源局下發(fā)通知要求10KV以上的新能源廠站要具備一次調頻能力,并遞交涉網(wǎng)試驗報告。對于投資規(guī)模不大的工商業(yè)分布式光伏電站,又要面臨改造投資問題,壓力較大。如何選擇質優(yōu)價廉的一次調頻產(chǎn)品
    的頭像 發(fā)表于 01-17 08:54 ?1198次閱讀
    光伏<b class='flag-5'>一次</b>調頻設備/<b class='flag-5'>一次</b>調頻裝置|光伏<b class='flag-5'>一次</b>調頻涉網(wǎng)試驗/光伏電站<b class='flag-5'>一次</b>調頻建設改造方案

    從共識到共行:拓普聯(lián)科關于“一次性做好”的團隊心智集結

    從共識到共行:拓普聯(lián)科關于“一次性做好”的團隊心智集結12月20日下午,拓普聯(lián)科VIP會議中心內(nèi)燈火通明,氣氛熱烈。肖嵐董事長步履沉穩(wěn)地走向講臺,面對臺下兩百余位匯聚堂的干部與員工,場以“團隊
    的頭像 發(fā)表于 12-29 10:34 ?5031次閱讀
    從共識到共行:拓普聯(lián)科關于“<b class='flag-5'>一次性</b>做好”的團隊心智集結

    解析一次消諧和二消諧的差異與應用場景

    在電力系統(tǒng)中,消諧裝置是保障系統(tǒng)穩(wěn)定運行的關鍵設備,它可以有效消除諧振過電壓,避免因諧振引發(fā)的設備損壞和停電事故。一次消諧器和微機消諧裝置,都可以用于PT柜,保護電壓互感器。 一次消諧器和微機消諧
    的頭像 發(fā)表于 12-11 11:33 ?519次閱讀

    基于環(huán)形隊列的UART收發(fā)回顯實驗

    問題。在本實驗中,我們使用環(huán)形隊列來實現(xiàn)實驗1的串口收發(fā)回顯,將串口接收到的數(shù)據(jù)暫存在隊列中,待完成一次接收后再將隊列中的數(shù)據(jù)全部發(fā)出去。
    的頭像 發(fā)表于 10-27 13:51 ?1983次閱讀
    基于環(huán)形<b class='flag-5'>隊列</b>的UART收發(fā)回顯實驗

    bootloader和APP燒錄,能不能一次性分別燒錄到對應的位置?

    目前我是用STM32 ST-LINK Utility將bootloader和APP分別下載到對應的地址分區(qū),那么各位有什么更好的辦法可以一次性的將這兩個文件燒錄? 主要是解決量產(chǎn)的問題,我也想找對應的DLL庫自己開發(fā)個上位機軟件來解決這個問題,但是并沒有找到有效的API
    發(fā)表于 09-25 06:34

    mailbox和消息隊列 recv兩會卡死怎么解決?

    如下面的線程,首先創(chuàng)建個消息隊列,在循環(huán)內(nèi)直接收消息隊列的內(nèi)的消息,不創(chuàng)建發(fā)送消息線程用于測試rt_mq_recv能否在指定時間內(nèi)返回超時的錯誤碼,實際測試第
    發(fā)表于 09-19 06:26

    固定式測斜儀多久需要校準一次?

    在結構物安全監(jiān)測領域,固定式測斜儀的校準頻率直接影響數(shù)據(jù)可靠。根據(jù)工程實踐與設備特性,科學制定校準計劃需綜合考量環(huán)境條件、使用強度及工程風險等級。那么固定式測斜儀多久需要校準一次?常規(guī)校準周期建議
    的頭像 發(fā)表于 08-13 14:47 ?798次閱讀
    固定式測斜儀多久需要校準<b class='flag-5'>一次</b>?

    地平線征程6B一次性成功點亮

    近日,地平線面向入門級主動安全領域的新代車載智能計算方案——征程6B一次性成功點亮!從回片上電到1V出圖僅用時23分鐘,征程6B再次刷新智駕計算方案點亮的行業(yè)速度!自2024年發(fā)布以來,地平線征程
    的頭像 發(fā)表于 07-16 17:35 ?1142次閱讀

    一次性血壓傳感器NPC-100T:精準監(jiān)測的無菌守護者

    在醫(yī)療領域,血壓監(jiān)測是評估患者生命體征、指導臨床決策的核心環(huán)節(jié)。傳統(tǒng)可重復使用的血壓傳感器雖然普及,但存在交叉感染風險、消毒成本高以及設備老化導致的精度下降等問題。一次性血壓傳感器NPC-100T
    的頭像 發(fā)表于 05-19 13:21 ?629次閱讀
    <b class='flag-5'>一次性</b>血壓傳感器NPC-100T:精準監(jiān)測的無菌守護者

    一次性使用近端流量傳感器@SENSIRION

    廣泛應用于呼吸設備中,使用群體為醫(yī)院、家庭護理和急診室的插管患者和無創(chuàng)通氣患者。近端流量傳感器用于從新生兒到成人的護理,其相關要求充滿多樣與挑戰(zhàn)。傳感器必須精
    的頭像 發(fā)表于 05-19 13:20 ?829次閱讀
    <b class='flag-5'>一次性</b>使用近端流量傳感器@SENSIRION

    一次消諧裝置與二消諧裝置區(qū)別、一次消諧器與二消諧器的區(qū)別

    一次消諧器與二消諧器是電力系統(tǒng)中用于抑制諧振過電壓的不同裝置,主要區(qū)別如下: 安裝位置:一次消諧器串聯(lián)于電壓互感器(PT)一次側中性點與地之間,直接承受高電壓;二
    的頭像 發(fā)表于 05-07 09:58 ?4262次閱讀
    <b class='flag-5'>一次</b>消諧裝置與二<b class='flag-5'>次</b>消諧裝置區(qū)別、<b class='flag-5'>一次</b>消諧器與二<b class='flag-5'>次</b>消諧器的區(qū)別

    一次性使用心電電極片性能測試 深圳

    一次性使用心電電極片性能測試 :YICE0196 心電電極電性能測試儀、 心電電極電性能測試儀(SEAM) 心電電極性能測試儀
    的頭像 發(fā)表于 03-19 11:27 ?1418次閱讀
    <b class='flag-5'>一次性</b>使用心電電極片性能測試 深圳<b class='flag-5'>一</b>測