Redis--14--BigKey 和 热点Key

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • BigKey
    • 1.什么是bigkey
    • 2.bigkey的危害
    • 3.发现bigkey
          • scan
    • 4.解决bigkey
  • 什么是热点Key?该如何解决
    • 1. 产生原因和危害
        • 原因
        • 危害
    • 2.发现热点key
        • 预估发现
        • 客户端发现
        • Redis发现
          • monitor命令
          • hotkeys
        • 抓取TCP包发现
    • 3. 解决热点key
        • 使用二级缓存
        • key分散


BigKey

1.什么是bigkey

bigkey是指key对应的value所占的内存空间比较大,例如一个字符串类型的value可以最大存到512MB,一个列表类型的value最多可以存储23-1个元素。

如果按照数据结构来细分的话,一般分为字符串类型bigkey和非字符串类型bigkey。

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

非字符串类型:哈希、列表、集合、有序集合,体现在元素个数过多。

bigkey无论是空间复杂度和时间复杂度都不太友好,下面我们将介绍它的危害。

2.bigkey的危害

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

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

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

  3. 网络拥塞:每次获取bigkey产生的网络流量较大

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

bigkey的存在并不是完全致命的:

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

3.发现bigkey

redis-cli --bigkeys可以命令统计bigkey的分布

image.png

但是在生产环境中,开发和运维人员更希望自己可以定义bigkey的大小,而且更希望找到真正的bigkey都有哪些,这样才可以去定位、解决、优化问题。

判断一个key是否为bigkey,只需要执行debug object key查看serializedlength属性即可,它表示 key对应的value序列化之后的字节数。

image.png

如果是要遍历多个,则尽量不要使用keys的命令,可以使用scan的命令来减少压力。

scan

Redis 从2.8版本后,提供了一个新的命令scan,它能有效的解决keys命令存在的问题。和keys命令执行时会遍历所有键不同,scan采用渐进式遍历的方式来解决 keys命令可能带来的阻塞问题,但是要真正实现keys的功能,需要执行多次scan。可以想象成只扫描一个字典中的一部分键,直到将字典中的所有键遍历完毕。scan的使用方法如下:

scan cursor [match pattern] [count number]

cursor :是必需参数,实际上cursor是一个游标,第一次遍历从0开始,每次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。

Match pattern :是可选参数,它的作用的是做模式的匹配,这点和keys的模式匹配很像。

Count number :是可选参数,它的作用是表明每次要遍历的键个数,默认值是10,此参数可以适当增大。

image.png

可以看到,第一次执行scan 0,返回结果分为两个部分:

第一个部分9就是下次scan需要的cursor

第二个部分是10个键。接下来继续

直到得到结果cursor变为0,说明所有的键已经被遍历过了。

除了scan 以外,Redis提供了面向哈希类型、集合类型、有序集合的扫描遍历命令,解决诸如hgetall、smembers、zrange可能产生的阻塞问题,对应的命令分别是hscan、sscan、zscan,它们的用法和scan基本类似,请自行参考Redis官网。

image.png

渐进式遍历可以有效的解决keys命令可能产生的阻塞问题,但是scan并非完美无瑕,如果在scan 的过程中如果有键的变化(增加、删除、修改),那么遍历效果可能会碰到如下问题:新增的键可能没有遍历到,遍历出了重复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键,这些是我们在开发时需要考虑的。

如果键值个数比较多,scan + debug object会比较慢,可以利用Pipeline机制完成。对于元素个数较多的数据结构,debug object执行速度比较慢,存在阻塞Redis的可能,所以如果有从节点,可以考虑在从节点上执行。

4.解决bigkey

主要思路为拆分

对 big key 存储的数据 (big value)进行拆分,变成value1,value2… valueN等等。

  • 例如big value 是个大json 通过 mset 的方式,将这个 key的内容打散到各个实例中,
  • 或者一个hash,每个field代表一个具体属性,通过hget、hmget获取部分value,hset、hmset来更新部分属性。
  • 例如big value 是个大list,可以拆成将list拆成。= list_1, list_2, list3, …listN

其他数据类型同理。

什么是热点Key?该如何解决

在Redis中,访问频率高的key称为热点key。

1. 产生原因和危害

原因

热点问题产生的原因大致有以下两种:

用户消费的数据远大于生产的数据(热卖商品、热点新闻、热点评论、明星直播)。

在日常工作生活中一些突发的事件,例如:双十一期间某些热门商品的降价促销,当这其中的某一件商品被数万次点击浏览或者购买时,会形成一个较大的需求量,这种情况下就会造成热点问题。同理,被大量刊发、浏览的热点新闻、热点评论、明星直播等,这些典型的读多写少的场景也会产生热点问题。

请求分片集中,超过单Server的性能极限。在服务端读数据进行访问时,往往会对数据进行分片切分,此过程中会在某一主机Server上对相应的Key进行访问,当访问超过Server极限时,就会导致热点Key问题的产生。

危害

1、流量集中,达到物理网卡上限。

2、请求过多,缓存分片服务被打垮。

3、DB击穿,引起业务雪崩。

2.发现热点key

预估发现

针对业务提前预估出访问频繁的热点key,例如秒杀商品业务中,秒杀的商品都是热点key。

当然并非所有的业务都容易预估出热点key,可能出现漏掉或者预估错误的情况。

客户端发现

客户端其实是距离key"最近"的地方,因为Redis命令就是从客户端发出的,以Jedis为例,可以在核心命令入口,使用这个Google Guava中的AtomicLongMap进行记录,如下所示。

使用客户端进行热点key的统计非常容易实现,但是同时问题也非常多:

(1) 无法预知key的个数,存在内存泄露的危险。

(2) 对于客户端代码有侵入,各个语言的客户端都需要维护此逻辑,维护成本较高。

(3) 规模化汇总实现比较复杂。

Redis发现
monitor命令

monitor命令可以监控到Redis执行的所有命令,利用monitor的结果就可以统计出一段时间内的热点key排行榜,命令排行榜,客户端分布等数据。

image.png

Facebook开源的redis-faina正是利用上述原理使用Python语言实现的,例如下面获取最近10万条命令的热点key、热点命令、耗时分布等数据。为了减少网络开销以及加快输出缓冲区的消费速度,monitor尽可能在本机执行。

此种方法会有两个问题:

1、monitor命令在高并发条件下,内存暴增同时会影响Redis的性能,所以此种方法适合在短时间内使用。

2、只能统计一个Redis节点的热点key,对于Redis集群需要进行汇总统计。

可以参考的框架:Facebook开源的redis-faina正是利用上述原理使用Python语言实现的

hotkeys

Redis在4.0.3中为redis-cli提供了–hotkeys,用于找到热点key。

image.png

如果有错误,需要先把内存逐出策略设置为allkeys-lfu或者volatile-lfu,否则会返回错误。

image.png

image.png

但是如果键值较多,执行较慢,和热点的概念的有点背道而驰,同时热度定义的不够准确。

抓取TCP包发现

Redis客户端使用TCP协议与服务端进行交互,通信协议采用的是RESP。如果站在机器的角度,可以通过对机器上所有Redis端口的TCP数据包进行抓取完成热点key的统计

此种方法对于Redis客户端和服务端来说毫无侵入,是比较完美的方案,但是依然存在3个问题:

(1) 需要一定的开发成本

(2) 对于高流量的机器抓包,对机器网络可能会有干扰,同时抓包时候会有丢包的可能性。

(3) 维护成本过高。

对于成本问题,有一些开源方案实现了该功能,例如ELK(ElasticSearch Logstash Kibana)体系下的packetbeat[2] 插件,可以实现对Redis、MySQL等众多主流服务的数据包抓取、分析、报表展示

3. 解决热点key

发现热点key之后,需要对热点key进行处理。

使用二级缓存
  • 可以使用guava-cache或hcache,发现热点key之后,将这些热点key加载到JVM中作为本地缓存。访问这些key时直接从本地缓存获取即可,不会直接访问到redis层了,有效的保护了缓存服务器。
key分散
  • 将热点key分散为多个子key,然后存储到缓存集群的不同机器上,这些子key对应的value都和热点key是一样的。当通过热点key去查询数据时,通过某种hash算法随机选择一个子key,然后再去访问缓存机器,将热点分散到了多个子key上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/208879.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解贝叶斯分类与朴素贝叶斯模型(Naive Bayes, NB):从基础到实战

目录 贝叶斯分类 公式 决策规则 优点 贝叶斯分类器的例子——垃圾邮件问题 1. 特征(输入): 2. 类别: 3. 数据: 4. 模型训练: 注:类别先验概率 5. 模型预测: 朴素贝叶斯模…

基于SSM框架开发的酒店后台管理系统

基于SSM框架开发的酒店后台管理系统 文章目录 基于SSM框架开发的酒店后台管理系统 一.引言二.系统设计三.技术架构四.功能实现五.界面展示六.源码获取 一.引言 酒店管理系统是一个集客房预订、前台管理、客户服务、财务管理等功能于一体的综合性软件系统。它能够帮助酒店高效地…

爬虫-xpath篇

1.xpath的基础语法 表达式描述nodename选中该元素/从根节点选取、或者是元素和元素间的过渡//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置.选取当前节点…选取当前节点的父节点选取属性text()选取文本 举例: 路径表达式结果html选择html元…

shell编程系列(10)-使用paste拼接列

使用paste拼接列 前言使用paste拼接列拼接两个文件 结语 前言 在前面的文章中讲解了使用cut命令选择列,这篇文章我们介绍使用paste命令拼接列,其实这个命令的使用场景很有限,做科研的同学可能才会用到,但是却非常好用&#xff0c…

游戏被流量攻击会有什么样的影响,该用什么样的防护方式去处理

德迅云安全-领先云安全服务与解决方案提供商德迅云游戏盾专门针对游戏进行防护,可免费提供防护方案~ 如果游戏被流量攻击会产生以下影响: 服务器过载:流量攻击会导致游戏服务器接收到的请求数量急剧增加,超出服务器的处理能力。这…

vue3中如何实现事件总线eventBus

使用插件 由于vue3中 “$ on”,$ off 和 $ once 实例方法已被移除,组件实例不再实现事件触发接口 所以我们可以使用官方推荐的这个第三方库实现同样的效果 mitt https://github.com/developit/mitt 安装 pnpm install mitt -S挂载全局写法 main.ts 初始…

网络编程之套接字

端口 && IP 在学习套接字编程之前,我们必须了解一下前缀知识。首先是IP和端口的作用。 在这之前,我们要明白一件事。那就是把数据从一台主机发送到另一台主机,是目的吗???当然不是!&a…

socket.io介绍

1. 使用的技术 Socket.IO 是一个封装了 Websocket、基于 Node 的 JavaScript 框架,包含 client 的 JavaScript 和 server 的 Node。其屏蔽了所有底层细节,让顶层调用非常简单。 另外,Socket.IO 还有一个非常重要的好处。其不仅支持 WebSocket…

leetcode:232. 用栈实现队列

一、题目 原题链接:232. 用栈实现队列 - 力扣(LeetCode) 函数原型: typedef struct //我的队列结构定义 { } MyQueue; MyQueue* myQueueCreate() //我的队列创建及其初始化 void myQueuePush(MyQueue* obj, int x) //我的队…

生成对抗网络——研讨会

时隔一年,再跟着李沐大师学习了GAN之后,仍旧没能在离散优化中实现通用的应用,实在惭愧,借着组内研讨会的机会,再队GAN的前世今生做一个简单的综述。 GAN产生的背景 目前与GAN相关的应用 去reddit社区的机器学习板块…

〖大前端 - 基础入门三大核心之JS篇㊺〗- 定时器和延时器

说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

基于helm的方式在k8s集群中部署gitlab - 升级(三)

接上一篇 基于helm的方式在k8s集群中部署gitlab - 部署(一),本篇重点对gitlab在k8s集群中进行升级 文章目录 1. gitlab 升级1.1 获取release1.2 下载目前版本的gitlab charts1.3 获取当前的values文件1.4 升级 2. gitlab数据库升级2.1 备份数…

力扣题:字符串的反转-11.22

力扣题-11.22 [力扣刷题攻略] Re:从零开始的力扣刷题生活 力扣题1:541. 反转字符串 II 解题思想:进行遍历翻转即可 class Solution(object):def reverseStr(self, s, k):""":type s: str:type k: int:rtype: str"&quo…

简单搭建Python开发环境

Python环境安装 Python官网: Welcome to Python.org 1. 选择Python3.x版本下载,建议使用稳定版3.9.13(Stable Releases),绝大数库对3.9版本Python已良好支持,但对3.10及以上支持不完全: https://www.…

SSM框架(六):SpringBoot技术及整合SSM

文章目录 一、概述1.1 简介1.2 起步依赖1.3 入门案例1.4 快速启动 二、基础配置2.1 三种配置文件方式2.2 yaml文件格式2.3 yaml读取数据方式(3种) 三、多环境开发3.1 yml文件-多环境开发3.2 properties文件-多环境开发3.3 多环境命令行启动参数设置3.4 多…

2023年腾讯云双12优惠活动整理汇总

2023年双12腾讯云推出了年末感恩回馈活动,年度爆款2核2G4M云服务器118元/年,新老用户同享,还可领取总面值2000元代金券,老用户服务器续费4折起。本文为大家整理汇总腾讯云双12优惠活动。 活动地址: 点此直达腾讯云双1…

JOSEF 快速中间继电器 KZJ-4H-L DC220V 导轨安装

快速中间继电器KZJ-4H-LDC220V导轨安装导轨安装是广泛用于电力系统,能够断货开或开通大负载,并且具有较强的断弧能力,适用于交流50/60Hz。电压24380V,直流电压24280V自动控制电路中以增加保护和控制回路的触点数量与触点容量。 KZJ系列快速中…

“B2B+OMS方案”,赋能家电巨头构建BC订单一体化能力,促进业务增长|徐礼昭

某国际知名家电电器品牌,年营收超过5000亿元。该电器企业其整体业务分三大类:线上线下B2B2C业务、线下B2B业务以及DTC零售业务。 随着业务的发展,该电器品牌对2B业务及DTC业务的数字化系统能力支撑需要更加全面和立体,以适应业务…

【Matlab】如何快速入门一项新技能-以Matlab/Simulink入门为例

目录 1. 引言 2. 背景 3. 快速学习并完成开发 3.1 了解需求,知道要干什么 3.2 了解Matlab/Simulink基本功能 第一步,查看Matlab的中文网站中文网站https://www.ilovematlab.cn/resources/对Matlab/Simulink有了一个初步认识。 3.3 实现一个最简单…

技术阅读周刊第第8️⃣期

技术阅读周刊,每周更新。 历史更新 20231103:第四期20231107:第五期20231117:第六期20231124:第七期 Prometheus vs. VictoriaMetrics (VM) | Last9 URL: https://last9.io/blog/prometheus-vs-victoriametrics/?refd…