Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > 监听Redis实时数据变化

监听Redis实时数据变化实现过程

作者:有女孩说要娶我

本文介绍了通过定时遍历Redis并对比缓存Map,实现监听指定前缀键的value变化的方法,并简要提及了可用Keyspace通知等更高效的手段

前言

监听Redis的Value实时变化。

一、实现思路

最简单粗暴的方式,首先遍历一遍数据存到map,然后不断遍历redis判断value是否跟已有的map值相等即可。

二、实现步骤

1. 定义缓存Map

假设需要监听数据key前缀为aaa,创建定时调度服务:

private static final Map<String, String> LAST_VALUES = new ConcurrentHashMap<>();
private static final String KEY_PREFIX = "aaa";
private ScheduledExecutorService scheduler;

2. 入口方法

使用@PostConstruct注解执行初始化:

    @PostConstruct
    public void init() {
        // 异步加载所有键值,不阻塞启动
        CompletableFuture.runAsync(this::loadInitialValues);

        // 每5秒扫描一次
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(this::scanChanges, 0, 5, TimeUnit.SECONDS);
    }

3. 初始化

使用Jedis创建连接,定义扫描参数,使用redis的scan命令遍历所有的匹配"aaa"+ "*"模式的键,游标从0开始,使用do-while,返回为0表示迭代结束,将所有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. 扫描变更数据

判断新旧数据是否一致,不一致则通过自定义方法处理数据:

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 {
                            //处理数据
                            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);
        }
    }

总结

本文介绍了最简单的监听Redis中value值的变化方法,还可以设置Redis Keyspace 通知监听。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文