我们使用lua脚本在更新我们的DB时执行批量删除数据。Jedis使用管道执行lua脚本。
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脚本阻塞了吗?
当我只使用管道进行批处理删除时,缓慢日志也会返回慢速查询。
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());
}发布于 2016-06-08 09:35:11
慢速日志能够单独存储前128个慢日志(可以在redis.conf慢速日志中进行更改)。因此,您使用LUA脚本的第一个模型肯定是一个阻塞模式。
如果你一个一个地删除这样一个数字(12470),它肯定是一个阻塞的数字,因为它需要更多的时间来完成。在这两个模型中,第二个模型对我来说很好(使用管道),因为您避免了迭代,只需多次按del query即可。
您可以使用每100或1000多个键的del (无论您在小测试后觉得最优)。您可以将它们组合到一个管道中。
或者,如果您可以在没有原子性的情况下进行同样的操作,那么您可以在一个循环中一次删除100或1000个键,这样就不会是阻塞调用。
尝试与不同的组合,采取的指标,并与优化的一个。
https://stackoverflow.com/questions/37693565
复制相似问题