关于redisson Unable to send PING command over channel 异常

问题描述

redis版本5.0.9,redisson的springboot-stater版本是3.24.2,redis中做了一个hash结构的缓存,里面的数据量比较大,有100多万个键值对,之前运行一直正常,最近突然频繁在提取缓存的时候报错:

ERROR [redisson-timer-4-1] 2024-11-19 21:53:38 (PingConnectionHandler.java:89) Unable to send PING command over channel: [id: 0x577dfd31, L:/191.168.0.110:59996 - R:191.168.0.110/191.168.0.110:6379]
org.redisson.client.RedisTimeoutException: Command execution timeout for command: (PING), params: [], Redis client: [addr=redis://191.168.0.110:6379]

当时用来提取hash所有键值对的方法是这样的:

 /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<String, T> hmget(String key) {
        HashOperations<String, String, T> stringObjectObjectHashOperations = redisTemplate.opsForHash();
        return stringObjectObjectHashOperations.entries(key);
    }

平时用这个方法去提取数据问题不大,也一直没有异常,直到最近缓存量大增,当键值对达到百万级,就出现了redisson的异常信息。

解决方法

解决这个问题的方法是采用Cursor游标提取,代码如下:

    /**
     * 批量获取hashKey对应的所有键值
     *
     * @param key
     * @return
     */
    public Map<String, T> hmgetBatch(String key) {
        Map<String, T> result = new HashMap<>();
        // 每次返回 SCAN_SIZE 条数据
        ScanOptions options = ScanOptions.scanOptions().count(SCAN_SIZE).build();
        try (Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, options)) {
            while (cursor.hasNext()) {
                Map.Entry<Object, Object> entry = cursor.next();
                result.put((String) entry.getKey(), (T) entry.getValue());
            }
        }
        return result;
    }

这样提取在速度上测试下来有10倍提升,同时也不再报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值