[Redis]怎么查看以xx开头的所有key?有什么坑?BigKey问题?
目录
1. keys 有坑
2. bigKey问题
2.1 big key 系列问题
什么是 big key
寻找big key(通过RDB分析,redis-cli分析)
优化big key
2.2 multiGet
1. keys 有坑
有坑!
因为服务器现在用的都是keys
比如之前我们用的清理token方法:
Set<String> keys = redisService.keys(RedisConstants.TOKEN + "*");redisService.del(keys);
但是,这个方法是停止别的插入为代价的,扫描之后得到key的集合。而且一次性获取所有key,key特别多的话就会很慢。
keys是遍历算法,时间复杂度是O(n) 这个命令非常容易导致Redis服务卡顿。因此,我们要尽量避免在生产环境使用该命令。
所以如果该机器是生产环境正在对外提供服务,不建议使用keys * pattern的方法进行查询,可能会使服务器卡顿,而出现事故。
一般生产服务器建议使用Scan命令,例如:
SCAN 0 MATCH xxx* COUNT 10
SCAN命令和SSCAN、HSCAN、ZSCAN命令都用于增量的迭代元素集,它每次返回小部分数据,不会像KEYS那样阻塞Redis。SCAN命令是基于游标的,每次调用后,都会返回一个游标,用于下一次迭代。当游标返回0时,表示迭代结束。
匹配xxx开头的key
因为scan是异步命令。虽然scan也是O(N)它是分次进行的,不会阻塞线程。
scan命令提供了limit参数,可以控制每次返回结果的最大条数。
2. bigKey问题
转自:bigkey问题
因为是个面试题:
数据量大的 key ,由于其数据大小远大于其他key,导致经过分片之后,某个具体存储这个 big key 的实例内存使用量远大于其他实例,造成内存不足,拖累整个集群的使用。big key 在不同业务上,通常体现为不同的数据,比如:
- 论坛中的大型持久盖楼活动;
- 聊天室系统中热门聊天室的消息列表;
bigkey 通常会导致内存空间不平衡,超时阻塞,如果 key 较大,redis 又是单线程,操作 bigkey 比较耗时,那么阻塞 redis 的可能性增大。每次获取 bigKey 的网络流量较大,假设一个 bigkey 为 1MB,每秒访问量为 1000,那么每秒产生 1000MB 的流量,对于普通千兆网卡,按照字节算 128M/S 的服务器来说可能扛不住。而且一般服务器采用单机多实例方式来部署,所以还可能对其他实例造成影响。
- 如果是集群模式下,无法做到负载均衡,导致请求倾斜到某个实例上,而这个实例的QPS会比较大,内存占用也较多;对于Redis单线程模型又容易出现CPU瓶颈,当内存出现瓶颈时,只能进行纵向库容,使用更牛逼的服务器。
- 涉及到大key的操作,尤其是使用hgetall、lrange、get、hmget 等操作时,网卡可能会成为瓶颈,也会到导致堵塞其它操作,qps 就有可能出现突降或者突升的情况,趋势上看起来十分不平滑,严重时会导致应用程序连不上,实例或者集群在某些时间段内不可用的状态。
- 假如这个key需要进行删除操作,如果直接进行DEL 操作,被操作的实例会被Block住,导致无法响应应用的请求,而这个Block的时间会随着key的变大而变长。
2.1 big key 系列问题
什么是 big key
- 字符串类型:一般认为超过 10k 的就是 bigkey,但是这个值和具体的 OPS 相关。
- 非字符串类型:体现在哈希,列表,集合类型元素过多。
寻找big key(通过RDB分析,redis-cli分析)
redis-cli自带
--bigkeys
。1 2
$ redis-cli -p 999 --bigkeys -i 0.1 #Scanning the entire keyspace to find biggest keys as well as average sizes per key type. You can use -i 0.1 to sleep 0.1 sec per 100 SCAN commands (not usually needed).
获取生产Redis的rdb文件,通过rdbtools分析rdb生成csv文件,再导入MySQL或其他数据库中进行分析统计,根据size_in_bytes统计bigkey
1 2 3 4
$ git clone https://github.com/sripathikrishnan/redis-rdb-tools $ cd redis-rdb-tools $ sudo python setup.py install $ rdb -c memory dump-10030.rdb > memory.csv
通过python脚本,迭代scan key,每次scan 1000,对扫描出来的key进行类型判断,例如:string长度大于10K,list长度大于10240认为是big bigkeys
其他第三方工具,例如:redis-rdb-cli
优化big key
优化big key的原则就是string减少字符串长度,list、hash、set、zset等减少成员数。
string类型的big key,建议不要存入redis,用文档型数据库MongoDB代替或者直接缓存到CDN上等方式优化。有些 key 不只是访问量大,数据量也很大,这个时候就要考虑这个 key 使用的场景,存储在redis集群中是否是合理的,是否使用其他组件来存储更合适;如果坚持要用 redis 来存储,可能考虑迁移出集群,采用一主一备(或1主多备)的架构来存储。
单个简单的key存储的value很大
2该对象需要每次都整存整取: 可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响;
该对象每次只需要存取部分数据: 可以像第一种做法一样,分拆成几个key-value,也可以将这个存储在一个hash中,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性。hash, set,zset,list 中存储过多的元素
可以将这些元素分拆。以hash为例,原先的正常存取流程是 hget(hashKey, field) ; hset(hashKey, field, value)
现在,固定一个桶的数量,比如 10000, 每次存取的时候,先在本地计算field的hash值,模除 10000,确定了该field落在哪个key上。(有点像集群插槽)
|
|
set, zset, list 也可以类似上述做法。但有些不适合的场景,比如,要保证 lpop 的数据的确是最早push到list中去的,这个就需要一些附加的属性,或者是在 key的拼接上做一些工作(比如list按照时间来分拆)。
2.2 multiGet
RedisTemplate的multiGet的操作
针对数据结构为String类型
示例代码
List<String> keys = new ArrayList<>(); for (Book e : booklist) {String key = generateKey.getKey(e);keys.add(key); } List<Serializable> resultStr = template.opsForValue().multiGet(keys);
转自:bigkey问题
https://www.jianshu.com/p/d5399fca2f72
[Redis]怎么查看以xx开头的所有key?有什么坑?BigKey问题?相关推荐
- 正则匹配以xx开头以xx结尾的单词
在字符串处理中,正则表达式是一大利器,但其对于初学者而言是存在一定的难度的. 而如何匹配以xx开头以xx结尾的单词呢? 假设需要匹配的字符串为:site sea sue sweet see case ...
- Python 正则匹配以xx开头以xx结尾的单词
参考 正则匹配以xx开头以xx结尾的单词 Python 正则表达式
- linux启动redis缓存查看的一些命令
查看启动 ps -ef|grep redis vi redis.conf 修改配置# 设置其他主机可以访问,注释掉下面配置 bind 127.0.0.1 设置为守护进程(默认值为no) daemoni ...
- Oracle 导出以XX开头的表结构及表数据并导入其他用户
使用expdp和impdp命令完成,这里只给出命令和命令中用到关键词的相关解释. 准备工作 在sqlplus的窗口中创建DIRECTORY,并且赋权限给用户 CREATE OR REPLACE DIR ...
- Redis如何查看key
Redis如何查看key 登录Linux服务器使用:whereis redis命令找到redis的位置 whereis redis 如果想查询所有redis有关文件,可以使用find查看 find - ...
- Redis配置查看及设置
Redis如何查看配置? Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf(Windows 名为 redis.windows.conf). 你可以通过 CONFIG ...
- redis 用户订单缓存_Redis实战(12)-基于Key失效和定时任务实现订单支付超时自动失效...
"商城平台用户下单"这一业务场景相信很多小伙伴并不陌生,在正常的情况下,用户在提交完订单/下完单之后,应该是前往"收银台"选择支付方式进行支付,之后只需要提供相 ...
- Unable to negotiate with XX.XX.XX.XX: no matching host key type found. Their offer: ssh-dss
本文 Github/javamap 已收录,有Java程序员进阶技术知识地图以及我的系列文章,欢迎大家Star. 在我把本地程序提交到远程分支上时 $ git push origin share_da ...
- Redis分片代理twemproxy快速搭建 | twemproxy Demo | twitter/ twemproxy 避坑指南 | autoconf-2.69下载
前言 1.代理分类 面对高可用.高扩展.易维护,用一款redis代理都是上佳的选择. redis代理主要有:predixy.twemproxy.codis.redis-cerberus. 2.性能优劣 ...
最新文章
- 【机器学习】基于蚁群算法的多元非线性函数极值寻优
- JavaEE Tutorials (15) - 对Java持久化API应用使用二级缓存
- python加减法视频教程免费_一起学opencv-python三十八(视频分析:背景减法)
- 老板不爽,同事不满,下属不服,是你违反了这10大团队管理原则
- php里面执行python,在php中执行python
- nginx指定配置文件启动
- Tensorflow object detection API 搭建自己的目标检测模型并迁移到Android上
- 【zookeeper】ZooKeeper 权限管理与Curator增加权限验证
- golang微服务框架对比_最强开源微服务框架,全网独家整理
- sql oltp_内存中的OLTP系列– SQL Server 2014上的数据迁移指南过程
- Kubernetes 小白学习笔记(13)--k8s集群路线-init流程
- React Native之原理浅析, iOS原理分析与实践解析、Android原理分析与实践解析
- 《C++程序设计实践》实验1
- 程序员可以培养的第二技能有哪些?
- java 网吧计费系统_java网吧计费管理系统
- 【智能制造】海阔凭鱼跃:记一场工业场景下的AI技术实践
- Docker容器dockerfile简介
- Github项目:AI消除马赛克实战
- rhel6.5 oracle12c,中标麒麟Linux6.5安装Oracle12C配置过程
- 炙手可热的ZNS SSD将会为数据中心带来什么?