异常信息
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内文章来源:https://www.toymoban.com/news/detail-627924.html
修改代码如下:文章来源地址https://www.toymoban.com/news/detail-627924.html
/**
* 批量删除
* @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);
}
}
}
到了这里,关于Redis ERR Protocol error: invalid multibulk length的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!