目录

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 在不同业务上,通常体现为不同的数据,比如:

  1. 论坛中的大型持久盖楼活动;
  2. 聊天室系统中热门聊天室的消息列表;

bigkey 通常会导致内存空间不平衡,超时阻塞,如果 key 较大,redis 又是单线程,操作 bigkey 比较耗时,那么阻塞 redis 的可能性增大。每次获取 bigKey 的网络流量较大,假设一个 bigkey 为 1MB,每秒访问量为 1000,那么每秒产生 1000MB 的流量,对于普通千兆网卡,按照字节算 128M/S 的服务器来说可能扛不住。而且一般服务器采用单机多实例方式来部署,所以还可能对其他实例造成影响。

  1. 如果是集群模式下,无法做到负载均衡,导致请求倾斜到某个实例上,而这个实例的QPS会比较大,内存占用也较多;对于Redis单线程模型又容易出现CPU瓶颈,当内存出现瓶颈时,只能进行纵向库容,使用更牛逼的服务器。
  2. 涉及到大key的操作,尤其是使用hgetall、lrange、get、hmget 等操作时,网卡可能会成为瓶颈,也会到导致堵塞其它操作,qps 就有可能出现突降或者突升的情况,趋势上看起来十分不平滑,严重时会导致应用程序连不上,实例或者集群在某些时间段内不可用的状态。
  3. 假如这个key需要进行删除操作,如果直接进行DEL 操作,被操作的实例会被Block住,导致无法响应应用的请求,而这个Block的时间会随着key的变大而变长。

2.1 big key 系列问题

什么是 big key

  1. 字符串类型:一般认为超过 10k 的就是 bigkey,但是这个值和具体的 OPS 相关。
  2. 非字符串类型:体现在哈希,列表,集合类型元素过多。

寻找big key(通过RDB分析,redis-cli分析)

  1. 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).
    
  2. 获取生产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
    
  3. 通过python脚本,迭代scan key,每次scan 1000,对扫描出来的key进行类型判断,例如:string长度大于10K,list长度大于10240认为是big bigkeys

  4. 其他第三方工具,例如:redis-rdb-cli

优化big key

优化big key的原则就是string减少字符串长度,list、hash、set、zset等减少成员数。

  1. string类型的big key,建议不要存入redis,用文档型数据库MongoDB代替或者直接缓存到CDN上等方式优化。有些 key 不只是访问量大,数据量也很大,这个时候就要考虑这个 key 使用的场景,存储在redis集群中是否是合理的,是否使用其他组件来存储更合适;如果坚持要用 redis 来存储,可能考虑迁移出集群,采用一主一备(或1主多备)的架构来存储。

  2. 单个简单的key存储的value很大

    2该对象需要每次都整存整取: 可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响;
    该对象每次只需要存取部分数据: 可以像第一种做法一样,分拆成几个key-value,也可以将这个存储在一个hash中,每个field代表一个具体的属性,使用hget,hmget来获取部分的value,使用hset,hmset来更新部分属性。

  3. hash, set,zset,list 中存储过多的元素

    可以将这些元素分拆。以hash为例,原先的正常存取流程是 hget(hashKey, field) ; hset(hashKey, field, value)
    现在,固定一个桶的数量,比如 10000, 每次存取的时候,先在本地计算field的hash值,模除 10000,确定了该field落在哪个key上。(有点像集群插槽)

1
2
3
newHashKey  =  hashKey + (hash(field) % 10000);
hset(newHashKey, field, value) ;
hget(newHashKey, field)

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问题?相关推荐

  1. 正则匹配以xx开头以xx结尾的单词

    在字符串处理中,正则表达式是一大利器,但其对于初学者而言是存在一定的难度的. 而如何匹配以xx开头以xx结尾的单词呢? 假设需要匹配的字符串为:site sea sue sweet see case ...

  2. Python 正则匹配以xx开头以xx结尾的单词

    参考 正则匹配以xx开头以xx结尾的单词 Python 正则表达式

  3. linux启动redis缓存查看的一些命令

    查看启动 ps -ef|grep redis vi redis.conf 修改配置# 设置其他主机可以访问,注释掉下面配置 bind 127.0.0.1 设置为守护进程(默认值为no) daemoni ...

  4. Oracle 导出以XX开头的表结构及表数据并导入其他用户

    使用expdp和impdp命令完成,这里只给出命令和命令中用到关键词的相关解释. 准备工作 在sqlplus的窗口中创建DIRECTORY,并且赋权限给用户 CREATE OR REPLACE DIR ...

  5. Redis如何查看key

    Redis如何查看key 登录Linux服务器使用:whereis redis命令找到redis的位置 whereis redis 如果想查询所有redis有关文件,可以使用find查看 find - ...

  6. Redis配置查看及设置

    Redis如何查看配置? Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf(Windows 名为 redis.windows.conf). 你可以通过 CONFIG ...

  7. redis 用户订单缓存_Redis实战(12)-基于Key失效和定时任务实现订单支付超时自动失效...

    "商城平台用户下单"这一业务场景相信很多小伙伴并不陌生,在正常的情况下,用户在提交完订单/下完单之后,应该是前往"收银台"选择支付方式进行支付,之后只需要提供相 ...

  8. 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 ...

  9. Redis分片代理twemproxy快速搭建 | twemproxy Demo | twitter/ twemproxy 避坑指南 | autoconf-2.69下载

    前言 1.代理分类 面对高可用.高扩展.易维护,用一款redis代理都是上佳的选择. redis代理主要有:predixy.twemproxy.codis.redis-cerberus. 2.性能优劣 ...

最新文章

  1. 【机器学习】基于蚁群算法的多元非线性函数极值寻优
  2. JavaEE Tutorials (15) - 对Java持久化API应用使用二级缓存
  3. python加减法视频教程免费_一起学opencv-python三十八(视频分析:背景减法)
  4. 老板不爽,同事不满,下属不服,是你违反了这10大团队管理原则
  5. php里面执行python,在php中执行python
  6. nginx指定配置文件启动
  7. Tensorflow object detection API 搭建自己的目标检测模型并迁移到Android上
  8. 【zookeeper】ZooKeeper 权限管理与Curator增加权限验证
  9. golang微服务框架对比_最强开源微服务框架,全网独家整理
  10. sql oltp_内存中的OLTP系列– SQL Server 2014上的数据迁移指南过程
  11. Kubernetes 小白学习笔记(13)--k8s集群路线-init流程
  12. React Native之原理浅析, iOS原理分析与实践解析、Android原理分析与实践解析
  13. 《C++程序设计实践》实验1
  14. 程序员可以培养的第二技能有哪些?
  15. java 网吧计费系统_java网吧计费管理系统
  16. 【智能制造】海阔凭鱼跃:记一场工业场景下的AI技术实践
  17. Docker容器dockerfile简介
  18. Github项目:AI消除马赛克实战
  19. rhel6.5 oracle12c,中标麒麟Linux6.5安装Oracle12C配置过程
  20. 炙手可热的ZNS SSD将会为数据中心带来什么?

热门文章

  1. Cocos Creator-5.物理与碰撞系统
  2. 马云出的面试题,你能做对吗?
  3. 目前最先进的神经网络算法,神经网络算法发展
  4. 拉手网@拉手族的团购记
  5. 产品经理(013)——产品思维练习
  6. 碎玻璃干法分选全介绍
  7. 一致性协议之 ZAB
  8. 大学计算机课教学特色,大学计算机基础课程教学探讨
  9. .section 后面跟着的“ax”是什么意思
  10. GDF307配置ADC单次采样