監(jiān)聽Redis實時數(shù)據(jù)變化實現(xiàn)過程
前言
監(jiān)聽Redis的Value實時變化。
一、實現(xiàn)思路
最簡單粗暴的方式,首先遍歷一遍數(shù)據(jù)存到map,然后不斷遍歷redis判斷value是否跟已有的map值相等即可。
二、實現(xiàn)步驟
1. 定義緩存Map
假設(shè)需要監(jiān)聽數(shù)據(jù)key前綴為aaa,創(chuàng)建定時調(diào)度服務(wù):
private static final Map<String, String> LAST_VALUES = new ConcurrentHashMap<>(); private static final String KEY_PREFIX = "aaa"; private ScheduledExecutorService scheduler;
2. 入口方法
使用@PostConstruct注解執(zhí)行初始化:
@PostConstruct
public void init() {
// 異步加載所有鍵值,不阻塞啟動
CompletableFuture.runAsync(this::loadInitialValues);
// 每5秒掃描一次
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(this::scanChanges, 0, 5, TimeUnit.SECONDS);
}3. 初始化
使用Jedis創(chuàng)建連接,定義掃描參數(shù),使用redis的scan命令遍歷所有的匹配"aaa"+ "*"模式的鍵,游標(biāo)從0開始,使用do-while,返回為0表示迭代結(jié)束,將所有value存到map:
private void loadInitialValues() {
try (Jedis jedis = new Jedis("localhost", 6379)) {
String cursor = "0";
ScanParams params = new ScanParams().match(KEY_PREFIX + "*").count(100);
do {
ScanResult<String> scanResult = jedis.scan(cursor, params);
cursor = scanResult.getCursor();
for (String key : scanResult.getResult()) {
String jsonString = jedis.get(key);
if (jsonString != null) {
LAST_VALUES.put(key, jsonString);
}
}
} while (!"0".equals(cursor));
log.info("Loaded {} initial values from Redis.", LAST_VALUES.size());
} catch (Exception e) {
throw new RuntimeException(e);
}
}4. 掃描變更數(shù)據(jù)
判斷新舊數(shù)據(jù)是否一致,不一致則通過自定義方法處理數(shù)據(jù):
private void scanChanges() {
try (Jedis jedis = new Jedis("localhost", 6379)) {
String cursor = "0";
ScanParams params = new ScanParams().match(KEY_PREFIX + "*").count(100);
do {
ScanResult<String> scanResult = jedis.scan(cursor, params);
cursor = scanResult.getCursor();
for (String key : scanResult.getResult()) {
String currentValueStr = jedis.get(key);
String oldValueStr = LAST_VALUES.getOrDefault(key, null);
if (!Objects.equals(currentValueStr, oldValueStr)) {
try {
//處理數(shù)據(jù)
dealWithData(key, oldValueStr, currentValueStr );
lastValues.put(key, currentValue);
LAST_VALUES.put(key, currentValueStr);
} catch (Exception e) {
log.error("Failed to process data change for key: {}", key, e);
}
}
}
} while (!"0".equals(cursor));
} catch (Exception e) {
throw new RuntimeException(e);
}
}總結(jié)
本文介紹了最簡單的監(jiān)聽Redis中value值的變化方法,還可以設(shè)置Redis Keyspace 通知監(jiān)聽。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
深入理解Redis內(nèi)存回收和內(nèi)存淘汰機制
Redis使用多種過期策略和內(nèi)存淘汰機制來管理內(nèi)存,本文主要介紹了深入理解Redis內(nèi)存回收和內(nèi)存淘汰機制, 具有一定的參考價值,感興趣的可以了解一下2024-06-06
Redis實戰(zhàn)之商城購物車功能的實現(xiàn)代碼
這篇文章主要介紹了Redis實戰(zhàn)之商城購物車功能的實現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02
redis 億級數(shù)據(jù)讀取的實現(xiàn)
本文主要介紹了redis 億級數(shù)據(jù)讀取的實現(xiàn),億級數(shù)據(jù)規(guī)模下實現(xiàn)高效的數(shù)據(jù)讀取成為了許多企業(yè)和開發(fā)者面臨的重大挑戰(zhàn),下面就來介紹一下,感興趣的可以了解一下2024-08-08
Redis高級玩法之利用SortedSet實現(xiàn)多維度排序的方法
Redis的SortedSet是可以根據(jù)score進行排序的,以手機應(yīng)用商店的熱門榜單排序為例,根據(jù)下載量倒序排列。接下來通過本文給大家分享Redis高級玩法之利用SortedSet實現(xiàn)多維度排序的方法,一起看看吧2019-07-07

