亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

關于codis對于原redis過期事件解決方案

發布時間:2020-07-02 10:28:05 來源:網絡 閱讀:5834 作者:jijun87120681 欄目:開發技術

1.     Redis處理過期事件方式

1.1.  Redis處理過期key方式

Redis key過期的方式有二:被動方式和主動方式
clients試圖訪問設置了過期時間且已過期的key時,為主動過期方式。
但僅是這樣是不夠的,以為可能存在一些key永遠不會被再次訪問到,這些設置了過期時間的key也是需要在過期后被刪除的。因此,Redis會周期性的隨機測試一批設置了過期時間的key并進行處理。測試到的已過期的key將被刪除。典型的方式為,Redis每秒做10次如下的步驟:
1.
隨機測試100個設置了過期時間的key
2.
刪除所有發現的已過期的key
3.
若刪除的key超過25個則重復步驟1

此為主動方式

1.2.  Redis處理過期事件

@Test
         public void testRedisEvent() {
 
                   Jedis jedis = newJedis("192.168.92.134", 8000);
                   jedis.psubscribe(newJedisPubSub() {
                            public voidonPMessage(String pattern, String channel,
                                               Stringmessage) {
                                     System.err.println(pattern);
                                     System.err.println(channel);
                                     System.err.println(message);
                            }
                   },"__keyevent@*__:expired");
         }

當監聽過期key時,則redis將此key通過pub/sub來發送事件。

由于codis不支持的命令包含了pub/sub,則codis不再支持此監聽事件。

2.     解決方案

2.1.  采用javaDelayQueue解決

DelayQueue介紹:Delayed 元素的一個×××阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部 是延遲期滿后保存時間最長的 Delayed元素。如果延遲都還沒有期滿,則隊列沒有頭部,并且 poll將返回 null。當一個元素的 getDelay(TimeUnit.NANOSECONDS)方法返回一個小于等于 0 的值時,將發生到期。即使無法使用 takepoll移除未到期的元素,也不會將這些元素作為正常元素對待。例如,size方法同時返回到期和未到期元素的計數。此隊列不允許使用 null 元素。

代碼如下:

public class RedisEvent<K, V> implements Runnable{
    public DelayQueue<DelayItem<Pair<K, V>>> q = new DelayQueue<DelayItem<Pair<K, V>>>();
    public void run() {
        while (true){
            DelayItem<Pair<K, V>> delayItem = null;
            try {
                delayItem = q.take();
                if (delayItem != null) {
                    // 超時對象處理
                    Pair<K, V> pair = delayItem.getItem();
                    System.out.println("key : " + pair.first + ", value : " + pair.second);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        RedisEvent<String, String> re = new RedisEvent<String, String>();
        //過期key,value
        Pair<String, String> pair1 = new Pair<String, String>("key1", "value1");
        //2秒過期
        DelayItem<Pair<String,String>> d1 = new DelayItem<Pair<String,String>>(pair1, TimeUnit.SECONDS.toNanos(2));
        re.q.add(d1);
        System.out.println(re.q.poll());

        Thread.sleep(1000 * 1);
        System.out.println(re.q.poll());
        //2秒后可以拿到數據
        Thread.sleep(1000 * 2);
        DelayItem<Pair<String,String>> delayItem = re.q.poll();
        System.out.println(delayItem);
        Pair<String, String> pair =delayItem.getItem();
        System.out.println("key : " + pair.first + ", value : " + pair.second);

        System.out.println(re.q.poll());

    }

輸出結果:

null
null
com.eric100.delayqueue.DelayItem@5054c2b8
key : key1, value : value1
null


此方案優缺點:

優點:自己實現,簡單易用,方便修改、擴展

缺點:當過期事件過多時且過期時間過長,需要DelayQueue存放過多key,消耗jvm內存

2.2.  使用第三方queue隊列實現

需要queue支持delay job,目前了解的有:Beanstalkdsidekiq

Beanstalkd介紹:

Beanstalk,一個高性能、輕量級的分布式內存隊列系統,最初設計的目的是想通過后臺異步執行耗時的任務來降低高容量Web應用系統的頁面訪問延遲,支持過有9.5 million用戶的Facebook Causes應用。

Beanstalkd設計里面的核心概念:

◆ job

一個需要異步處理的任務,是Beanstalkd中的基本單元,需要放在一個tube中。

◆ tube

一個有名的任務隊列,用來存儲統一類型的job,是producer和consumer操作的對象。

◆ producer

Job的生產者,通過put命令來將一個job放到一個tube中。

◆ consumer

Job的消費者,通過reserve/release/bury/delete命令來獲取job或改變job的狀態。

Beanstalkd中一個job的生命周期如圖2所示。一個job有READY, RESERVED, DELAYED, BURIED四種狀態。當producer直接put一個job時,job就處于READY狀態,等待consumer來處理,如果選擇延遲 put,job就先到DELAYED狀態,等待時間過后才遷移到READY狀態。consumer獲取了當前READY的job后,該job的狀態就遷移到RESERVED,這樣其他的consumer就不能再操作該job。當consumer完成該job后,可以選擇delete, release或者bury操作;delete之后,job從系統消亡,之后不能再獲取;release操作可以重新把該job狀態遷移回READY(也 可以延遲該狀態遷移操作),使其他的consumer可以繼續獲取和執行該job;有意思的是bury操作,可以把該job休眠,等到需要的時候,再將休 眠的job kick回READY狀態,也可以deleteBURIED狀態的job。正是有這些有趣的操作和狀態,才可以基于此做出很多意思的應用,比如要實現一個循環隊列,就可以將RESERVED狀態的 job休眠掉,等沒有READY狀態的job時再將BURIED狀態的job一次性kick回READY狀態。

優點:不需要自己實現,使用第三方queue

缺點:

1. Beanstalkd目前沒有提供主從同步+故障切換機制,在應用中有可能成為單點的風險。在實際應用中,可以使用數據庫為job提供持久化存儲。

2. 需要花費成本學習第三方queue

2.3.  使用數據庫實現

將過期keyvalue放入數據庫中,使用線程定時掃描數據庫。

關于codis對于原redis過期事件解決方案

關于codis對于原redis過期事件解決方案


啟動三個線程:

線程1:根據過期時間,掃描狀態為delay且過期時間已到的事件,將狀態改為ready

線程2:處理狀態為ready的事件,將ready狀態改為done

線程3:刪除done狀態的事件

優點:數據持久化,不會丟失事件數據

缺點:線程定時掃描,過期事件存在延遲處理

2.4.  使用redis實現(推薦)

由于codis不支持pub/sub,則重新添加redis服務,此服務只用來做過期事件處理

優點:實現方式與原來相同,不需要修改任何代碼

缺點:需要添加機器來做redis服務,主備需采用keepalive等處理


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

卓资县| 宁河县| 宜宾市| 新和县| 东辽县| 上思县| 阿图什市| 石城县| 克东县| 汽车| 北安市| 宣武区| 广安市| 黎城县| 象州县| 安义县| 个旧市| 宿迁市| 五华县| 察哈| 图木舒克市| 区。| 万州区| 宣威市| 永善县| 蓝田县| 和硕县| 霍城县| 秦皇岛市| 张家港市| 恭城| 邻水| 土默特左旗| 汶上县| 墨江| 吉安县| 阿巴嘎旗| 边坝县| 上犹县| 岑巩县| 宿州市|