首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lua脚本上的Jedis/Redis SocketTimeout异常

问Lua脚本上的Jedis/Redis SocketTimeout异常
EN

Stack Overflow用户
提问于 2016-06-08 04:56:25
回答 1查看 291关注 0票数 0

我们使用lua脚本在更新我们的DB时执行批量删除数据。Jedis使用管道执行lua脚本。

代码语言:javascript
复制
local result = redis.call('lrange',key,0,12470)
for i,k in ipairs(result) do
   redis.call('del',k)
   redis.call('ltrim',key,1,k)
end

try (Jedis jedis = jedisPool.getResource()) {
        Pipeline pipeline = jedis.pipelined();
        long len = jedis.llen(table);
         String script = String.format(DELETE_LUA_SCRIPT, table, len);
    LOGGER.info(script);
    pipeline.eval(script);
    pipeline.sync();
    } catch (JedisConnectionException e) {
        LOGGER.info(e.getMessage());
    }

对于大范围,我们注意到lua脚本慢下来,我们得到SocketTimeOutExceptions。

运行redis-cli缓慢日志只显示执行时间过长的lua脚本。

有更好的方法吗?我的lua脚本阻塞了吗?

当我只使用管道进行批处理删除时,缓慢日志也会返回慢速查询。

代码语言:javascript
复制
try (Jedis jedis = jedisPool.getResource()) {
        Pipeline pipeline = jedis.pipelined();
        long len = jedis.llen(table);
        List<String> queriesContainingTable = jedis.lrange(table,0,len);
        if(queriesContainingTable.size() > 0) {
            for (String query: queriesContainingTable) {
                pipeline.del(query);
                pipeline.lrem(table,1,query);
            }
            pipeline.sync();
        }
    } catch (JedisConnectionException e) {
        LOGGER.info("CACHE INVALIDATE FAIL:"+e.getMessage());
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-08 09:35:11

慢速日志能够单独存储前128个慢日志(可以在redis.conf慢速日志中进行更改)。因此,您使用LUA脚本的第一个模型肯定是一个阻塞模式。

如果你一个一个地删除这样一个数字(12470),它肯定是一个阻塞的数字,因为它需要更多的时间来完成。在这两个模型中,第二个模型对我来说很好(使用管道),因为您避免了迭代,只需多次按del query即可。

您可以使用每100或1000多个键的del (无论您在小测试后觉得最优)。您可以将它们组合到一个管道中。

或者,如果您可以在没有原子性的情况下进行同样的操作,那么您可以在一个循环中一次删除100或1000个键,这样就不会是阻塞调用。

尝试与不同的组合,采取的指标,并与优化的一个。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37693565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档