KeySpaceNotification 鍵空間通知


KeySpaceNotification 鍵空間通知

1、Redis鍵淘汰機制簡介

在Redis中,內存的大小是有限的,所以為了防止內存飽和,需要實現某種鍵淘汰策略。主要有兩種方法,一種是當Redis內存不足時所采用的內存釋放策略。第二種是對過期鍵進行刪除的策略,也可以在某種程度上釋放內存。

1.1 Redis鍵過期淘汰的策略

當需要進行內存釋放的時候,需要用某種策略對保存的的對象進行刪除。Redis有六種策略:

volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰

volatile-ttl:從已設置過期時間的數據集中挑選將要過期的數據淘汰

volatile-random:從已設置過期時間的數據集中任意選擇數據淘汰

allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰

allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰

no-enviction(驅逐):禁止驅逐數據

2、KeySpaceNotification功能

2.1 開啟KeySpaceNotification功能

默認情況下,該功能是關閉的,因為該功能消耗部分CPU。開啟該功能需要修改redis的配置文件。

當前需要修改的配置的機器有兩台:Redis1、Redis2

配置文件的路徑均為: /etc/redis

clip_image002

圖1 Redis1中需要修改的配置文件

clip_image004

圖2 Redis2中需要修改的配置文件

2.2 修改配置文件

1. 使用vi 6379.conf 進入文件;

clip_image006

圖3 使用vi指令進入配置文件

2. 輸入/keyspace,回車后定位到該功能開啟部分;

clip_image008

圖4 定位keyspace

clip_image009

圖4 查看通知功能介紹

3. 修改配置文件為下圖所示 KEA表示所有的操作都會向相應的頻道中發布通知信息;

clip_image011

圖5 修改后的配置文件

4. 按下Esc,輸入:wq! 回車保存文件;

5. 按照上述過程將所有的配置文件。

6. 重啟Redis1、Redis2,使鍵空間通知功能開啟。

3、使用鍵空間通知功能

3.1 實現頻道的訂閱

public class jedisSubscribe {

public static void main(String[] args) {

  Set<HostAndPort> jedisClusterNodes=new HashSet<HostAndPort>();

  JedisCluster cluster;

  cluster = new JedisCluster(RedisPool.loadServers());

  String host1 = "192.168.1.34";

  JedisPubSub jedisPubSub = null;

  jedisPubSub = new JedisPubSub() {

  /*

  * 常規模式:關閉訂閱時觸發arg0 key值 arg1 訂閱數量

  */

  public void onUnsubscribe(String arg0, int arg1) {

  }

  /*

  * 常規模式:啟動訂閱時觸發arg0 key值 arg1 訂閱數量

  */

  public void onSubscribe(String arg0, int arg1) {

    System.out.println("Success onSubscribe "+arg0);

  }

  /*

  * 常規模式:收到匹配key值的消息時觸發arg0 key值arg1 收到的消息值

  */

  public void onMessage(String arg0, String arg1) {

    System.out.println("Get Message "+arg1);

    System.out.println("Get "+arg0);

    String key = cluster.get(arg0);

    System.out.println("Success "+key);

  }

  /*

  * 正則模式:關閉正則類型訂閱時觸發

  * arg0 key的正則表達式arg1 訂閱數量

  */

  public void onPUnsubscribe(String arg0, int arg1) {
  
  }

  /*

  * 正則模式:啟動正則類型訂閱時觸發

  * arg0 key的正則表達式

  * arg1 訂閱數量

  */

  public void onPSubscribe(String arg0, int arg1) {
  
  }

  /*

  * 正則模式:收到匹配key值的消息時觸發

  * arg0訂閱的key正則表達式

  * arg1匹配上該正則key值

  * arg2收到的消息值

  */

  public void onPMessage(String arg0, String arg1, String arg2) {
  
  }

};

  String channel4 = "__keyevent@0__:expire";//設置訂閱的頻道channels

  JedisPool jedisPool1 = new JedisPool(host1);

  jedisPool1.getResource().subscribe(jedisPubSub, channel4);

  }

}

 

3.2 對Redis中的鍵進行操作

public static void main(String[] args) throws InterruptedException {

  Set<HostAndPort> jedisClusterNodes=new HashSet<HostAndPort>();

  JedisCluster cluster;

  cluster = new JedisCluster(RedisPool.loadServers());

  String key = "name";//設置一個key

  String value = "zpf";//設置該key的value

  cluster.set(key, value);//向redis中寫入該(key,value)

  cluster.expire(key, 2);//設置key過期時間為2秒

  cluster.del(key);

}

 

3.3 運行結果

clip_image013

4.車輛信息的實時性維護

4.1利用鍵空間通知的方法

Redis會在設置過期時間的鍵集合中隨機抽選進行鍵的判斷,如果過期則進行刪除操作,同時會向頻道 __keyevent@0__:expire中過期消息,並且監聽這個頻道的程序會得到過期的鍵是哪一個鍵。也會向頻道 __keyspace@0__:key中發布該鍵過期的消息,其中這里的頻道根據過期的鍵key不同發布的頻道也不同。進行刪除操作時,Redis也會向頻道__keyevent@0__:del和 __keyspace@0__:key中分別發布消息。

為了維護車輛信息的實時性,需要對過期的車輛數據進行相應的刪除操作,但是Redis中的刪除操作只能將對應的key刪除掉,這里的需求是進行網格以及其他相應的維護操作,刪除操作是不相同的。因此需要再刪除之前得到過期的key的值value。

clip_image015

clip_image017

根據上面的描述,無法再訂閱頻道__keyevent@0__:expire接收到通知的時候得到過期鍵的值value。為了實現借助Redis的刪除功能需要在該頻道接收到信息之前得到要過期的key的值value。但是這樣的話又成了對redis的判斷操作。為了實現得到過期鍵的value,可以通過在得到該數據並進行設置過期時間的時候提前構造一個map<key,value>其中key為車牌,value為車牌+原始信息的value。這樣在頻道__keyevent@0__:expire接收到通知時,就可以使用map得到相應的value值。

4.2 使用該方法造成的問題

構造map時,需要對每一輛車進行判斷,如果車牌key不在此map中時,需要將該信息放入map中;如果車牌key存在此map中,需要更新map。那么存儲該map需要占用額外的存儲空間。

5.參考資料

http://redis.io/topics/notifications

https://cnodejs.org/topic/5577b493c4e7fbea6e9a33c9#5577e266c4e7fbea6e9a3449

http://redisdoc.com/topic/notification.html#id1

http://blog.csdn.net/caishenfans/article/details/44902651

https://github.com/antirez/redis/issues/594


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM