bigkey是指key对应的value所占的内存空间比较大,例如一个字符串类型的value 可以最大存到512MB,—个列表类型的value最多可以存储2^32-1个元素。如果按照数据结构来细分的话,一般分为字符串类型bigkey和非字符串类型bigkey。

□ 字符串类型:体现在单个value值很大,一般认为超过10KB就是bigkey,但这个值和具体的OPS相关。

□ 非字符串类型:哈希、列表、集合、有序集合,体现在元素个数过多。bigkey无论是空间复杂度和时间复杂度都不太友好,下面我们将介绍它的危害。

1.bigkey的危害

  bigkey的危害体现在三个方面:

□ 内存空间不均匀(平衡):例如在Redis Cluster中,bigkey会造成节点的内存空间使用不均匀。

□ 超时阻塞:由于Redis单线程的特性,操作bigkey比较耗时,也就意味着阻塞Redis可能性增大。

□ 网络拥塞:每次获取bigkey产生的网络流量较大,假设一个bigkey为 1MB, 每秒访问量为1000,那么每秒产生1000MB的流量,对于普通的千兆网卡(按照字节算是 128MB/S) 的服务器来说简直是灭顶之灾,而且一般服务器会采用单机多实例的方式来部署,也就是说一个bigkey可能会对其他实例造成影响,其后果不堪设想。

  bigkey的存在并不是完全致命的,如果这个bigkey存在但是几乎不被访问,那么只有内存空间不均匀的问题存在,相对于另外两个问题没有那么重要紧急,但是如果bigkey是一个热点key (频繁访问),那么其带来的危害不可想象,所以在实际开发和运维时一定要密切关注bigkey的存在。

2.如何发现big key

  redis-cli --bigkeys可以命令统计bigkey的分布,但是在生产环境中,开发和运维人员更希望自己可以定义bigkey的大小,而且更希望找到真正的bigkey都有哪些,这样才可以去定位、解决、优化问题。判断一个key是否为bigkey,只需要执行debug object key查看serializedlength属性即可,它表示key对应的value序列化之后的字节数,例如我们执行如下操作:

127.0.0.1:6379 > debug object key
Value at: 0x7fc06c1b1430 refcount:1 encoding:raw serialized length:1256350 lru:11686193 lru_seconds_idle:20

  可以发现serialized length=11686193字节,约1M,同时可以看到encoding是 raw,也就是字符串类型,那么可以通过strlen来看一下字符串的字节数为2247394字节,约为2MB:

127.0.0.1:6379> strlen key
(integer) 2247394

  serialized length 不代表真实的字节大小,它返回对象使用RDB编码序列化后的长度,值会偏小,但是对于排查bigkey有一定辅助作用,因为不是每种数据结构都有类似s trlen这样的方法。

  在实际生产环境中发现bigkey的两种方式如下:

□ 被动收集:许多开发人员确实可能对bigkey不了解或重视程度不够,但是这种bigkey—旦大量访问,很可能就会带来命令慢查询和网卡跑满问题,开发人员通过对异常的分析通常能找到异常原因可能是bigkey, 这种方式虽然不是被推荐的,但是在实际生产环境中却大量存在,建议修改Redis客户端,当抛出异常时打印出所操作的key,方便排查bigkey问题。

□ 主动检测:scan + debug object:如果怀疑存在bigkey,可以使用scan命令渐进的扫描出所有的key,分别计算每个key的serializedlength,找到对应bigkey进行相应的处理和报警,这种方式是比较推荐的方式。

  建议提示:

□ 如果键值个数比较多,scan + debug object会比较慢,可以利用Pipeline机制完成。

□ 对于元素个数较多的数据结构,debug object执行速度比较慢,存在阻塞Redis的可能。

□ 如果有从节点,可以考虑在从节点上执行。

3.如何删除

  当发现Redis中有bigkey并且确认要删除时,如何优雅地删除bigkey? 无论是什么数据结构,del命令都将其删除。但是相信通过上面的分析后你一定不会这么做,因为删除b igkey通常来说会阻塞Redis服务。下面给出一组测试数据分别对string、hash、list、set、sorted set 五种数据结构的bigkey进行删除,bigkey的元素个数和每个元素的大小不尽相同。

  下面测试和服务器硬件、Redis版本比较相关,可能在不同的服务器上执行速度不太相同,但是能提供一定的参考价值。

  表12-3展示了删除512KB ~ 10MB的字符串类型数据所花费的时间,总体来说由于字符串类型结构相对简单,删除速度比较快,但是随着value值的不断增大,删除速度也逐渐变慢。

表 12-3 删除字符串类型耗时

key类型

512KB

1MB

2MB

5MB

10MB

string

0.22ms

0.31ms

0.32ms

0.56ms

1ms

  表12-4展示了非字符串类型的数据结构在不同数量级、不同元素大小下对bigkey执行del命令的时间,总体上看元素个数越多、元素越大,删除时间越长,相对于字符串类型,这种删除速度已经足够可以阻塞Redis。

表12-4 删除hash、list、set、sorted set四种数据结构不同数量不同元素大小的耗时

key 类型

10万(8个字节)

100万(8 个字节)

10万(16 个字节)

100万(1 6个字节 )

10万(128 个字节)

100万(12 8 字节

hash

51ms

950ms

58ms

970ms

96ms

2000ms

list

23ms

134ms

23ms

138ms

23ms

266ms

set

44ms

873ms

58ms

881ms

73ms

1319ms

sorted set

51ms

845ms

57ms

859ms

59ms

969ms

  从上分析可见,除了string类型,其他四种数据结构删除的速度有可能很慢,这样增大了阻塞Redis的可能性。既然不能用del命令,那有没有比较优雅的方式进行删除呢,这时候就要用到scan 命令的若干类似命令拿出来:sscan、hscan、zscan。

  1.string

  对于string 类型使用del命令一般不会产生阻塞:

del bigkey

  2.hash、list、set、sorted set

  比如hash,使用hscan命令,每次获取部分(例如 100个)field-value,再利用hd el删除每个field (为了快速可以使用Pipeline)。

4.最佳实践思路

  由于开发人员对Redis的理解程度不同,在实际开发中出现bigkey在所难免,重要的是,能通过合理的检测机制及时找到它们,进行处理。作为开发人员在业务开发时应注意不能将Redis简单暴力的使用,应该在数据结构的选择和设计上更加合理,例如出现了bigkey, 要思考一下可不可以做一些优化(例如拆分数据结构)尽量让这些bigkey消失在业务中,如果bigkey不可避免,也要思考一下要不要每次把所有元素都取出来(例如有时候仅仅需要hmget, 而不是hgetall)。最后,可喜的是,Redis将在 4.0 版本支持lazy delete fr ee的模式,删除bigkey不会阻塞Redis。

Redis big key处理的更多相关文章

  1. Redis 键(key)相关的命令及其它命令的查看地址

    Redis 键(key) Redis 键命令用于管理 redis 的键. 语法 Redis 键命令的基本语法如下: redis 127.0.0.1:6379> COMMAND KEY_NAME ...

  2. redis入门(05)redis的key命令

    一.什么是redis键命令 Redis 键(key):Redis 键命令用于管理 redis 的键. Redis 键命令的基本语法: redis 127.0.0.1:6379> COMMAND ...

  3. Redis设置Key/value的规则定义和注意事项(附工具类)

    对于redis的存储key/value键值对,经过多次踩坑之后,我们总结了一套规则:这篇文章主要讲解定义key/value键值对时的定义规则和注意事项. 前面一篇文章讲了如何定义Redis的客户端和D ...

  4. redis的key越来越多,对速度是否有影响

    ---恢复内容开始--- redis存储key是用字典对象的,查询性能几乎和数量级无关,只要保证内存够用就可以了,如果内存不够,会把内存和swap空间交换,这种情况下就会很影响性能,会读取出现读取磁盘 ...

  5. Redis的key和value大小限制

    Redis的key和value大小限制        今天研究了下将java bean序列化到redis中存储起来,突然脑袋灵光一闪,对象大小会不会超过redis限制?不管怎么着,还是搞清楚一下比较好 ...

  6. redis中key过期事件

    刚到新公司一个月左右,有个新需求,想做定时任务,比如在用户注册时间的3天后推送用户一条消息. 从刚开始脑子里面闪现的数据库轮询,立马否定掉(浪费资源),再到linux系统的定时任务,但是当用户量过大时 ...

  7. redis的key

    Redis支持的数据模型: Redis支持的数据类型: redis的key: Redis对key的操作: 执行命令cd  /usr/local/redis进入到redis的启动目录,执行./redis ...

  8. 7.redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?

    作者:中华石杉 面试题 redis 集群模式的工作原理能说一下么?在集群模式下,redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗? 面试官心理分析 在前几年, ...

  9. redis 下key的过期时间详解 :expire

    memcached 和 redis 的set命令都有expire参数,可以设置key的过期时间.但是redis是一个可以对数据持久化的key-value database,它的key过期策略还是和me ...

  10. Redis 根据Key模糊批量查询数据

    前言 经常会有这样一种业务逻辑,就是需要根据Redis中Key的规则,模糊查询对应的数据,当数据量少时,利用常规的命令也能满足需求,但是数据量大时,就会导致堵塞,就算是采用不堵塞的函数,如果数据需要显 ...

随机推荐

  1. [Scala] 面向对象

    类定义 当属性是private时,scala会自动为其生成get和set方法 只希望scala生成get,不生成set,可定义为常量 不生成get和set方法,使用private[this]关键字 1 ...

  2. [Python] execl读写

    相关库 读:xlrd 写:xlwt 案例 要求: 将图1中的数据导以图2的形式写入另一个文件中 第一列索引关系:{1:K1-B1,2:K1-B2} ...(18列) 思路: 按行读取数据,根据索引关系 ...

  3. 云计算OpenStack---云计算、大数据、人工智能(14)

    一.互联网行业及云计算 在互联网时代,技术是推动社会发展的驱动,云计算则是一个包罗万象的技术栈集合,通过网络提供IAAS.PAAS.SAAS等资源,涵盖从数据中心底层的硬件设置到最上层客户的应用.给我 ...

  4. 3.socket编程示例

    #block_server.py 非阻塞IO示例#有个疑惑:下面的connfd的blockind要设置为True,不然会出错,待解决from socket import *from time impo ...

  5. MyBatis 各种参数传递方式

    MyBatis参数传递方式 情况一:Mapper映射器接口方法参数只有一个且为基本类型 接口方法: public List<UserEntity> selectUserByAge(int ...

  6. MyBatis 全局配置文件详解(七)

    MyBatis 配置文件作用 MyBatis配置文件包含影响 MyBatis 框架正常使用的功能设置和属性信息.它的作用好比手机里的设置图标,点击这个图标就可以帮助我们查看手机的属性信息和设置功能.其 ...

  7. 为何存在uwsgi还要使用nginx

    nginx是对外的服务接口,外部浏览器通过url访问nginx,nginx接收到浏览器发送过来的http请求,将包解析分析url,如果是静态文件则直接访问用户给nginx配置的静态文件目录,直接返回用 ...

  8. maven工具使用json-lib时,JSONArray.fromObject()不能执行的解决方案

    前端代码我就不展示了 ,下面说明下我遇到问题的情况,如果不想看可以直接划到黄色字体部分直接找解决方法哦~~(相关jar包我会放在云中,想要的自己下载哦,链接在视频最下面!!) 我的pom文件,如下,导 ...

  9. docker swarm外部验证负载均衡时不生效

    问题描述 我在本地创建了3个装了centos7的虚拟机, 并初始化了swarm集群, 即1个manager节点, 2个worker节点; 三台机子的ip分别是 192.168.124.8 - (man ...

  10. Jenkins 基础篇 - 任务创建

    前面了解了 Jenkins 上各种任务的区别后,我们就来实践应用下,先创建一个[文件夹]类型的任务,将我们目前的一些基础的演示任务[移动]到文件夹里面去,这样可以先做个简单的分类. 新建一个[文件夹] ...