我们正在使用lua脚本对数据库更新进行批量删除。 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 slowlog只显示执行时间太长的lua脚本。
有更好的方法吗?是我的lua脚本阻止?
当我只使用管道进行批量删除时,slowlog也会返回慢查询。
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());
}
答案 0 :(得分:0)
slowlog能够单独存储前128个慢速日志(可以在redis.conf中更改slowlog-max-len 128)。因此,使用LUA脚本的第一个模型肯定是阻塞的。
如果您逐个删除这样的号码(12470),肯定是一个阻塞号码,因为它需要更多时间才能完成。在2个模型中,第二个对我来说很好(使用管道),因为你避免迭代所做的就是n次查询del查询。
您可以每100或1000使用多个键的del(在小测试后您认为最佳)。您可以将它们分组到管道中。
或者,如果您可以在没有原子性的情况下执行相同操作,则可以在循环中一次删除每100或1000个键,这样它就不会成为阻塞调用。
尝试使用不同的组合来获取指标并使用优化的指标。