Poison

关于 @Cacheable 使用 spring-data-redis 对接 Redis 作为缓存实现时指定 allEntries = true 后触发了 keys 命令导致其他命令 block 的问题

该问题笔者在 2020 年 02 月 04 日排查线上 Redis 性能抖动时发现,当时 spring-data-redis 的 @Cacheable 对 allEntries = true 的实现机制仅有 keys 命令一种,当时笔者仅将项目中 allEntries = true 调整为指定 key 的方式绕开了对 keys 命令的调用,最近看到 spring-data-redis 已经新增了对 SCAN 命令的支持。

@Cacheable allEntries = true

如果查看 Redis 官网中对 KEYS pattern 命令的介绍就能知道,该命令时间复杂度为 O(N),并且在警告中提到,应谨慎在生产环境中使用,若在大型数据库上执行该命令,可能导致糟糕的性能,此命令应用于调试或其他指定的操作,不要在常规的应用程序代码中使用 KEYS 命令,如果你在寻找一种在整个键空间中查询键的子集的方式,请考虑使用 SCAN 或 sets 命令。

在 2020 年 05 月 21 日有人在 GitHub 提出了关于该问题的 issue: DefaultRedisCacheWriter.clean() uses blocking KEYS command [DATAREDIS-1151] #1721

基于 SCAN 命令的实现在 2021 年 04 月 21 日被提交,参考:Add support for configurable batch strategies using RedisCache.