关于Redis大键(Key),我们从[空间复杂性]和访问它的[时间复杂度]两个方面来定义大键。前者主要表示Redis键的占用内存大小;后者表示Redis集合数据类型(set/hash/list/sorted set)键,所含有的元素个数。以下两个示例:

1个大小200MB的String键(String Object最大512MB),内存空间占用较大;1个包含100000000(1kw)个字段的Hash键,对应访问模式(如hgetall)时间复杂度高

因为内存空间复杂性处理耗时都非常小,测试 del 200MB String键耗时约1毫秒,而删除一个含有1kw个字段的Hash键,却会阻塞Redis进程数十秒。所以本文只从时间复杂度分析大的集合类键。删除这种大键的风险,以及怎么优雅地删除。

在Redis集群中,应用程序尽量避免使用大键;直接影响容易导致集群的容量和请求出现”倾斜问题“,具体分析见文章:redis-cluster-imbalance。但在实际生产过程中,总会有业务使用不合理,出现这类大键;当DBA发现后推进业务优化改造,然后删除这个大键;如果直接删除它,DEL命令可能阻塞Redis进程数十秒,对应用程序和Redis集群可用性造成严重的影响。

一、直接删除大Key的风险

DEL命令在删除单个集合类型的Key时,命令的时间复杂度是O(M),其中M是集合类型Key包含的元素个数。

DEL keyTime complexity: O(N) where N is the number of keys that will be removed. When a key to remove holds a value other than a string, the individual complexity for this key is O(M) where M is the number of elements in the list, set, sorted set or hash. Removing a single key that holds a string value is O(1).

生产环境中遇到过多次因业务删除大Key,导致Redis阻塞,出现故障切换和应用程序雪崩的故障。测试删除集合类型大Key耗时,一般每秒可清理100w~数百w个元素; 如果数千w个元素的大Key时,会导致Redis阻塞上10秒可能导致集群判断Redis已经故障,出现故障切换;或应用程序出现雪崩的情况。

说明:Redis是单线程处理。单个耗时过大命令,导致阻塞其他命令,容易引起应用程序雪崩或Redis集群发生故障切换。所以避免在生产环境中使用耗时过大命令。

Redis删除大的集合键的耗时, 测试估算,可参考;和硬件环境、Redis版本和负载等因素有关

Key类型

Item数量

耗时

Hash

~100万

~1000ms

List

~100万

~1000ms

Set

~100万

~1000ms

Sorted Set

~100万

~1000ms

当我们发现集群中有大key时,要删除时,如何优雅地删除大Key?

二、如何优雅地删除各类大Key

从Redis2.8版本开始支持SCAN命令,通过m次时间复杂度为O(1)的方式,遍历包含n个元素的大key.这样避免单个O(n)的大命令,导致Redis阻塞。 这里删除大key操作的思想也是如此。

2.1  Delete Large Hash Key

通过hscan命令,每次获取500个字段,再用hdel命令,每次删除1个字段。Python代码:

def del_large_hash():

r = redis.StrictRedis(host='redis-host1', port=6379)

large_hash_key ="xxx"

cursor = '0'

while cursor != 0:

cursor, data = r.hscan(large_hash_key, cursor=cursor, count=500)

for item in data.items():

r.hdel(large_hash_key, item[0])

2.2  Delete Large Set Key

删除大set键,使用sscan命令,每次扫描集合中500个元素,再用srem命令每次删除一个键Python代码:

def del_large_set():

r = redis.StrictRedis(host='redis-host1', port=6379)

large_set_key = 'xxx'

cursor = '0'

while cursor != 0:

cursor, data = r.sscan(large_set_key, cursor=cursor, count=500)

for item in data:

r.srem(large_size_key, item)

2.3  Delete Large List Key

删除大的List键,未使用scan命令; 通过ltrim命令每次删除少量元素。Python代码:

def del_large_list():

r = redis.StrictRedis(host='redis-host1', port=6379)

large_list_key = 'xxx'

while r.llen(large_list_key)>0:

r.ltrim(large_list_key, 0, -101)

2.4  Delete Large Sorted set key

删除大的有序集合键,和List类似,使用sortedset自带的zremrangebyrank命令,每次删除top 100个元素。Python代码:

def del_large_sortedset():

r = redis.StrictRedis(host='large_sortedset_key', port=6379)

large_sortedset_key='xxx'

while r.zcard(large_sortedset_key)>0:

r.zremrangebyrank(large_sortedset_key,0,99)

三、Redis Lazy Free

应该从3.4版本开始,Redis会支持lazy delete free的方式,删除大键的过程不会阻塞正常请求。

php redis hash删除key,如何优雅的删除Redis的大key相关推荐

  1. redis使用sysc超时_优雅的处理Redis访问超时

    很长一段时间以来,一直在项目中使用Redis作为辅助存储,确切来说是利用Redis的内存存储,而不是将其作为缓存.比如常见的利用Set集合来判断某个数值是否存在,或者将来自不同请求的数据放在Redis ...

  2. redis中有key但是删不掉_Redis大 key的发现与删除方法全解析

    个推作为国内第三方推送市场的早期进入者,专注于为开发者提供高效稳定的推送服务,经过9年的积累和发展,服务了包括新浪.滴滴在内的数十万APP.由于我们推送业务对并发量.速度要求很高,为此,我们选择了高性 ...

  3. redis中有key但是删不掉_Redis大key的发现与删除方法全解析

    个推作为国内第三方推送市场的早期进入者,专注于为开发者提供高效稳定的推送服务,经过9年的积累和发展,服务了包括新浪.滴滴在内的数十万APP.由于我们推送业务对并发量.速度要求很高,为此,我们选择了高性 ...

  4. Redis进阶-如何发现和优雅的处理BigKey一二事

    文章目录 PreView 模拟写入一个BigKey 如何发现BigKey redis-cli --bigkeys debug object 如何优雅的删除BigKey (lazy delete) 关于 ...

  5. Redis 笔记(13)— scan 和 keys 寻找特定前缀key 字段(命令格式、使用示例、定位大key)

    1. keys Redis 提供了一个简单暴力的指令 keys 用来列出所有满足特定正则字符串规则的 key. 127.0.0.1:6379> keys * (empty array) 127. ...

  6. 华为云企业级Redis评测第二期:大Key操作的影响

    点击蓝字 关注我们 在前一篇文章<华为云企业级Redis评测第一期:稳定性与扩容表现> 中,我们使用多线程压测工具memtier_benchmark对华为GaussDB(for Redis ...

  7. 深度评测丨GaussDB(for Redis)大Key操作的影响

    本文分享自华为云社区<墨天轮评测:GaussDB(for Redis)大Key操作的影响>,作者: 高斯 Redis 官方博客. 在前一篇文章<墨天轮评测:GaussDB(for R ...

  8. 技术解读丨分布式缓存数据库Redis大KEY问题定位及优化建议

    摘要:如何定位分布式缓存数据库Redis大KEY问题,实操案例带你掌握优化方法. [背景] 访问Redis 5.0 cluster集群出现OOM报错,报错信息为(error) OOM command ...

  9. Redis——大Key问题

    上一篇文章讲了Redis的热点key问题,本篇介绍Redis大Key问题的概念,大Key问题产生的原因.危害以及解决大Key问题的思路: 1. 什么是大key?多大算大key? 其实关于"大 ...

最新文章

  1. (chap3 数据链路)MAC地址
  2. ubuntu使用rabbitmq的一些基本命令
  3. angular图片上传
  4. qgis折点打断_arcgis在折点处打断并建立网络分析(最短路径等问题)
  5. CSS(网页样式语言)基础
  6. 又是一个github吗? Kubernetes 初创公司 Heptio被VMware 收购
  7. 关于Linux下ISE和vivado安装cable usb驱动的问题
  8. log4j配置(很详细)
  9. HBuild——创建表格
  10. ps无法在此计算机上,为什么电脑安装不了ps?
  11. 输出边长为n的正六边形(c语言)
  12. 「面试」缓存知识点大总结
  13. LayoutTransiton实现简单的录制按钮
  14. debian通过odbc连接mysql_PHP从Debian Etch使用ODBC和FreeTDS访问MSSQL数据库
  15. Java中Lambada表达式使用方法
  16. 深度学习数学基础——矩阵微分篇
  17. iOS---学习研究大牛Git高星项目YYCategories(四)
  18. 计算机文秘办公文员,计算机WORD文秘EXCEL文员PPT办公软件培训
  19. 每个人都是从零开始,分享牛逼的前端工程师的牛逼学习方法
  20. 美国南加州大学研究生计算机专业申请条件,美国南加州大学计算机研究生申请条件有哪些呢...

热门文章

  1. 5G毫米波手机天线等技术领域的专家 香港城大陆贵文教授再次获得殊荣
  2. input标签disabled和readonly属性的区别
  3. 《软件测试和质量管理》实验报告1——白盒测试
  4. 【Matplotlib】绘制基本图表
  5. Qt模拟Linux终端 1 - Linux指令调用
  6. 什么是值传递,什么是引用传递?
  7. python aes 加盐 加密解密
  8. 非编系统非编系统,何为非编系统?
  9. 〖Python零基础入门篇㊹〗- 自定义异常 [raise 关键字]
  10. 牛客 美团编程真题 MT1 最大差值 基础贪心 蓝书上的例题