Redis ERR Protocol error: invalid multibulk length

异常信息 

org.springframework.data.redis.RedisConnectionFailureException: ERR Protocol error: invalid multibulk length; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: ERR Protocol error: invalid multibulk length


Caused by: redis.clients.jedis.exceptions.JedisConnectionException: ERR Protocol error: invalid multibulk length
	at redis.clients.jedis.Connection.sendCommand(Connection.java:138) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.BinaryClient.del(BinaryClient.java:132) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.BinaryJedis.del(BinaryJedis.java:291) ~[jedis-2.9.0.jar!/:?]
	at org.springframework.data.redis.connection.jedis.JedisKeyCommands.del(JedisKeyCommands.java:121) ~[spring-data-redis-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
	... 38 more
Caused by: java.net.SocketException: Broken pipe (Write failed)
	at java.net.SocketOutputStream.socketWrite0(Native Method) ~[?:1.8.0_111]
	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109) ~[?:1.8.0_111]
	at java.net.SocketOutputStream.write(SocketOutputStream.java:153) ~[?:1.8.0_111]
	at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:52) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:76) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.util.RedisOutputStream.write(RedisOutputStream.java:66) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:100) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.Protocol.sendCommand(Protocol.java:84) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.Connection.sendCommand(Connection.java:127) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.BinaryClient.del(BinaryClient.java:132) ~[jedis-2.9.0.jar!/:?]
	at redis.clients.jedis.BinaryJedis.del(BinaryJedis.java:291) ~[jedis-2.9.0.jar!/:?]
	at org.springframework.data.redis.connection.jedis.JedisKeyCommands.del(JedisKeyCommands.java:121) ~[spring-data-redis-2.1.9.RELEASE.jar!/:2.1.9.RELEASE]
	... 38 more

报错原因: redis 执行条件过长 

错误代码: 


    /**
     * 批量删除
     * @param   prex为迷糊匹配的key,如cache:user:* 
     */
    public void redisDeleteByPrex(String prex) {
        Set<String> keys = redisTemplate.keys(prex);
        if (CollectionUtils.isNotEmpty(keys)) { 
        		redisTemplate.delete(keys); 
        }
    }

这里采用前匹配查询,获取到需要删除的数据超过 1M 所以报错

1M 这个结果来自  redis源码:

/* We know for sure there is a whole line since newline != NULL,
         * so go ahead and find out the multi bulk length. */
        redisAssertWithInfo(c,NULL,c->querybuf[0] == '*');
        ok = string2ll(c->querybuf+1,newline-(c->querybuf+1),&ll);
        if (!ok || ll > 1024*1024) {
            addReplyError(c,"Protocol error: invalid multibulk length");
            setProtocolError(c,pos);
            return REDIS_ERR;
        }

参考: https://blog.csdn.net/sinat_29843547/article/details/77512585

解决方案:

将查询结果分批处理 控制大小在1M内

修改代码如下:

    /**
     * 批量删除
     * @param   prex为迷糊匹配的key,如cache:user:* 
     */
    public void redisDeleteByPrex(String prex) {
        Set<String> keys = redisTemplate.keys(prex);
        if (CollectionUtils.isNotEmpty(keys)) {
        	List<String> list = new ArrayList<>(keys);
        	// 为防止查出的数据过大分批删除  一次10w
        	List<List<String>> splitList = CommonUtil.splitList(list, 100000);
        	for (List<String> list2 : splitList) {
        		redisTemplate.delete(list2);
			}
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值