浅谈Redis的keys命令到底有多慢
keys命令的用法:
keys pattern
查找符合正则匹配的key的列表。扫描对象是Redis服务中所有的key,想想都很慢对不对?
同时执行keys命令的同时,Redis进程将被阻塞,无法执行其他命令,假如超过了哨兵的down-after-milliseconds
配置,还会进行主从切换,切换过程中,如果主节点恢复正常,还可能出现脑裂等一系列问题。
所以,生产环境中,建议直接禁用keys命令。
Keys命令的替代方案
1、scan扫描,避免阻塞
2、将需要统计的数据放入一个set中 (但是这样可能出现Big Key问题,一般数据量大就不推荐)
Keys命令在Redis Cluster中是怎样执行的?
一般来说,keys命令对于集群节点来说,是不知道路由到哪个节点的,不像 get命令。在Java的Jedis客户端的JedisClusterKeyCommands
类中,我们看到:
public Set<byte[]> keys(byte[] pattern) { // 在每个节点执行keys命令 Collection<Set<byte[]>> keysPerNode = connection.getClusterCommandExecutor() .executeCommandOnAllNodes((JedisClusterCommandCallback<Set<byte[]>>) client -> client.keys(pattern)) .resultsAsList(); // 合并成一个整体后返回 Set<byte[]> keys = new HashSet<>(); for (Set<byte[]> keySet : keysPerNode) { keys.addAll(keySet); } return keys; }
我们看到,Jedis是通过在每个节点上执行keys命令,并将结果合并返回的。
本文既然将keys命令的慢,那么他到底有多慢呢?
Keys命令到底有多慢?
这里主要是给大家一个基本的概念,并不是深入剖析。
这是腾讯云上Redis集群服务中,慢查询的日志。我们看到,Keys命令大概执行了250ms ~ 300ms。
根据节点信息,我们看到,每个节点存储了大约153w的key
,占用内存300M+
,平均每个键值对占用内存0.208KB
,合213个字节
。
根据我的理解,既然keys命令返回的是key值,而集群中其实有一个结构slots_to_keys
记录着所有key 的, 这只与key的数量有关,与Big key的关系不大。
按照这种猜想,假如此时Redis节点占用内存为3G,且Key数量成比例,那么Keys命令执行时间因为3s左右,这段时间Redis节点是阻塞的。
到此这篇关于浅谈Redis的keys命令到底有多慢的文章就介绍到这了,更多相关Redis keys命令内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
相关推荐
-
Redis命令使用技巧之Keys的相关操作
前言 介绍完Redis连接相关命令后,再来介绍一下与Key相关的命令,Redis作为一个key-value数据库,对Key进行操作是无法避免的. KEYS 的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 key ,你最好还是用 Redis 的集合结构(set)来代替. DEL 最早可用版本1.0.0 删除指定的键值对,如果指定的key不存在,则忽略.DEL命令的时间复杂度是O(N),对于除字符串外的其他数据类型,命令的时间复杂度为O(M),M是值
-
redis 用scan指令 代替keys指令(详解)
众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会阻塞服务器,对单线程的redis来说,简直是灾难,终于找到了替代命令scan. SCAN cursor [MATCH pattern] [COUNT count] SCAN 命令及其相关的 SSCAN 命令. HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incrementally iterate)一集元素(a collection of elements): SCAN 命令用于迭代当前数据库中的数据库键. S
-
Redis 不使用 keys 命令获取键值信息的方法
1. 问题来源 这个问题可能看起来很奇怪,但很多 redis 集群会有一个统一的入口,入口会作兼容 redis 命令的代理,一般出于新能考虑是禁止使用 keys 命令来获取键值信息的,但是可以通过 scan 命令来代替 keys 2. 使用 keys 的方法 127.0.0.1:6379> KEYS * 1) "_kombu.binding.test_queue" 2) "a8e620b9-e52e-3498-8a1c-448f35783058" 3) &qu
-
Redis遍历所有key的两个命令(KEYS 和 SCAN)
当我们需要遍历Redis所有key或者指定模式的key时,首先想到的是KEYS命令: KEYS pattern 官网对于KEYS命令有一个提示: KEYS 的速度非常快,例如,Redis在一个有1百万个key的数据库里面执行一次查询需要的时间是40毫秒 .但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 KEYS , 你最好还是用 Redis 的集合结构 SETS 来代替. KEYS命令使用很简单. redis> MSET one 1 two 2 thr
-
解决spring中redistemplate不能用通配符keys查出相应Key的问题
有个业务中需要删除某个前缀的所有Redis缓存,于是用RedisTemplate的keys方法先查出所有合适的key,再遍历删除. 但是在keys(patten+"*")时每次取出的都为空. 解决问题: spring中redis配置中,引入StringRedisTemplate而不是RedisTemplate,StringRedisTemplate本身继承自RedisTemplate, 即 <bean id="redisTemplate" class=&quo
-
Redis的KEYS 命令千万不能乱用
KESY 命令 时间复杂度: O(N) , 假设Redis中的键名和给定的模式的长度有限的情况下,N为数据库中key的个数. Redis Keys 命令用于查找所有符合给定模式 pattern 的 key 尽管这个操作的时间复杂度是 O(N), 但是常量时间相当低.例如,在一个普通笔记本上跑Redis,扫描100万个key只要40毫秒. 命令格式 KEYS pattern Warning: 生产环境使用 KEYS 命令需要非常小心.在大的数据库上执行命令会影响性能.这个命令适合用来调试和特殊操作
-
redis keys与scan命令的区别说明
redis keys和scan的区别 redis的keys命令,通常在用来删除相关key时使用,但这个命令有一个弊端,在redis拥有数百万及以上的keys时,执行速度会比较慢,更致命的是,这个命令会阻塞redis多路复用的io主线程,如果这个线程阻塞,在此期间,其他发向redis服务端的命令,都会被阻塞,从而引发一系列级联反应,导致瞬间相应卡顿,从而引发超时等问题,所以应该在生产环境禁止用使用keys和类似的命令smembers,这种时间复杂度为O(N),且会阻塞主线程的命令,是非常危险的.
-
在RedisTemplate中使用scan代替keys指令操作
keys * 这个命令千万别在生产环境乱用.特别是数据庞大的情况下.因为Keys会引发Redis锁,并且增加Redis的CPU占用.很多公司的运维都是禁止了这个命令的 当需要扫描key,匹配出自己需要的key时,可以使用 scan 命令 scan操作的Helper实现 import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.
-
浅谈Redis的keys命令到底有多慢
keys命令的用法: keys pattern 查找符合正则匹配的key的列表.扫描对象是Redis服务中所有的key,想想都很慢对不对? 同时执行keys命令的同时,Redis进程将被阻塞,无法执行其他命令,假如超过了哨兵的down-after-milliseconds配置,还会进行主从切换,切换过程中,如果主节点恢复正常,还可能出现脑裂等一系列问题. 所以,生产环境中,建议直接禁用keys命令. Keys命令的替代方案 1.scan扫描,避免阻塞 2.将需要统计的数据放入一个set中 (但是
-
浅谈redis的maxmemory设置以及淘汰策略
redis的maxmemory参数用于控制redis可使用的最大内存容量.如果超过maxmemory的值,就会动用淘汰策略来处理expaire字典中的键. 关于redis的淘汰策略: Redis提供了下面几种淘汰策略供用户选择,其中默认的策略为noeviction策略: · noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错. · allkeys-lru:在主键空间中,优先移除最近未使用的key. · volatile-lru:在设置了过期时间的键空间中,优
-
浅谈redis缓存在项目中的使用
背景 Redis 是一个开源的内存数据结构存储系统. 可以作为数据库.缓存和消息中间件使用. 支持多种类型的数据结构. Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence). 通过 Redis 哨兵(Sentinel)和 Redis 集群(Cluster)的自动分区,提供高可用性(high availability). 基本数
-
浅谈Redis安全策略
目录 命令配置密码 手动配置密码 指令安全 端口安全 SSH代理 补充: 1. 开启redis密码认证,并设置高复杂度密码 2. 禁止监听在公网 3. 禁止使用root用户启动 4. 限制redis 配置文件访问权限 5. 修改默认6379端口 6. 禁用或者重命名危险命令 7. 打开保护模式 8. redis集群设置密码 9. 使用Redis5.0版本创建的集群设置密码 Redis 提供了诸多安全策略,比如为了保证数据安全,提供了设置密码的功能.Redis 密码设置主要有两种方式:一种是使用C
-
浅谈redis的过期时间设置和过期删除机制
目录 一:设置过期时间 二:保存过期时间 三:移除过期时间 四:计算并返回剩余生存时间 五:过期键的删除策略 六:redis使用的策略 一:设置过期时间 redis有四种命令可以用于设置键的生存时间和过期时间: EXPIRE <KEY> <TTL> : 将键的生存时间设为 ttl 秒 PEXPIRE <KEY> <TTL> :将键的生存时间设为 ttl 毫秒 EXPIREAT <KEY> <timestamp> :将键的过期时间设为
-
浅谈Redis 中的过期删除策略和内存淘汰机制
目录 前言 Redis 中 key 的过期删除策略 1.定时删除 2.惰性删除 3.定期删除 Redis 中过期删除策略 从库是否会脏读主库创建的过期键 内存淘汰机制 内存淘汰触发的最大内存 有哪些内存淘汰策略 内存淘汰算法 LRU LFU 为什么数据删除后内存占用还是很高 内存碎片如何产生 碎片率的意义 如何清理内存碎片 总结 参考 前言 Redis 中的 key 设置一个过期时间,在过期时间到的时候,Redis 是如何清除这个 key 的呢? 这来分析下 Redis 中的过期删除策略和内存淘
-
浅谈Redis 中的过期删除策略和内存淘汰机制
目录 前言 Redis 中 key 的过期删除策略 1.定时删除 2.惰性删除 3.定期删除 Redis 中过期删除策略 从库是否会脏读主库创建的过期键 内存淘汰机制 内存淘汰触发的最大内存 有哪些内存淘汰策略 内存淘汰算法 LRU LFU 为什么数据删除后内存占用还是很高 内存碎片如何产生 碎片率的意义 如何清理内存碎片 总结 参考 前言 Redis 中的 key 设置一个过期时间,在过期时间到的时候,Redis 是如何清除这个 key 的呢? 这来分析下 Redis 中的过期删除策略和内存淘
-
浅谈Redis缓冲区机制
目录 Redis缓冲区机制 客户端缓冲机制 应对输入缓冲区溢出 查看输入缓冲区信息 如何解决输入缓冲区溢出 应对输出缓冲区溢出 Monitor命令的执行 输出缓冲区设置不合理 主从集群中的缓冲区 复制缓冲区 复制缓冲区溢出 复制积压缓冲区 解决复制积压缓冲区溢出 Redis缓冲区机制 Redis中的缓冲区机制就是为了平衡客户端发送命令和服务端处理命令的速度差异,如果客户端写入过快或者服务端读取过慢这就会导致缓冲区溢出,缓冲区一旦溢出将引发一系列的性能问题,下面我们详细聊聊. 客户端缓冲机制 Re
-
浅谈Redis常见延迟问题定位与分析
目录 使用复杂度高的命令 存储bigkey 集中过期 实例内存达到上限 fork耗时严重 绑定CPU 使用Swap 网卡负载过高 使用复杂度高的命令 如果在使用Redis时,发现访问延迟突然增大,如何进行排查? 首先,第一步,建议你去查看一下Redis的慢日志.Redis提供了慢日志命令的统计功能,我们通过以下设置,就可以查看有哪些命令在执行时延迟比较大. 首先设置Redis的慢日志阈值,只有超过阈值的命令才会被记录,这里的单位是微妙,例如设置慢日志的阈值为5毫秒,同时设置只保留最近1000条慢
-
浅谈Redis阻塞的9种情况
目录 命令阻塞 SAVE 阻塞 同步持久化 AOF 重写 AOF 日志 大 Key 问题 查找大 key 删除大 key 清空数据库 集群扩容 前两天去美团面试的陈同学回来了,看他满脸泄气的样子,准是没拿到 Offer. 听了他面试的经过,真替他感到惋惜.究其原因,是被一道面试题拦住了去路:看你简历上写着精通 Redis,请你总结一下 Redis 中存在的阻塞问题吧. 正好阿Q这几天正在研究 Redis,就顺便在这儿给大家做个总结. 命令阻塞 使用不当的命令造成客户端阻塞: keys * :获取
随机推荐
- CSS选择符说明
- JQuery中如何传递参数如click(),change()等具体实现
- java中this与super关键字的使用方法
- Swift自定义iOS中的TabBarController并为其添加动画
- php 远程包含文件漏洞分析第1/6页
- C#实现组合排列的方法
- js实现div闪烁原理及实现代码
- 用ASP+DLL实现WEB方式修改服务器时间
- 奇特的js写法,或许可以用来加密躲杀毒软件什么的
- java使用Jsoup组件生成word文档
- javascript把15位身份证转成18的函数
- JS 终止执行的实现方法
- nginx中path模式配置示例
- 在MAMP环境下安装MySQLdb的方法
- 详解Java的Hibernate框架中的set映射集与SortedSet映射
- 浅谈Python中的可变对象和不可变对象
- 超简单的几行代码搞定Android底部导航栏功能
- App开发建议技巧
- 解决layui中table异步数据请求不支持自定义返回数据格式的问题
- 详解eclipse将项目打包成jar文件的两种方法及问题解决方法