当前位置: 首页 > news >正文

【Redis】redis大key和大value的危害,如何处理?

前序

还记得上次和同事一起去面试候选人时,同事提了一个问题:Redis的大key有什么危害?当时候选人主要作答的角度是一个key的value较大时的情况,比如:

  1. 内存不均:单value较大时,可能会导致节点之间的内存使用不均匀,间接地影响key的部分和负载不均匀;
  2. 阻塞请求:redis为单线程,单value较大读写需要较长的处理时间,会阻塞后续的请求处理;
  3. 阻塞网络:单value较大时会占用服务器网卡较多带宽,可能会影响该服务器上的其他Redis实例或者应用。

虽说答的是挺好的,但是我又随之产生了另一个疑惑,如果redis的key较长时,会产生什么样的影响呢?查了很多文章,说的都不是特别清楚。所以我决心探究一下这个问题。
我们需要知道Redis是如何存储key和value的:
根结构为RedisServer,其中包含RedisDB(数据库)。而RedisDB实际上是使用Dict(字典)结构对Redis中的kv进行存储的。这里的key即字符串,value可以是string/hash/list/set/zset这五种对象之一。
在这里插入图片描述

Dict字典结构中,存储数据的主题为DictHt,即哈希表。而哈希表本质上是一个DictEntry(哈希表节点)的数组,并且使用链表法解决哈希冲突问题(关于哈希冲突的解决方法可以参考大佬的文章 解决哈希冲突的常用方法分析)。

所以在这里实际存储时,key和value都是存储在DictEntry中的。所以基本上来说,大key和大value带来的内存不均和网络IO压力都是一致的,只是key相较于value还多一个做hashcode和比较的过程(链表中进行遍历比较key),会有更多的内存相关开销。

结论

  • 大key和大value的危害是一致的:内存不均、阻塞请求、阻塞网络。
  • key由于比value需要做更多的操作如hashcode、链表中比较等操作,所以会比value更多一些内存相关开销。

我们需要知道Redis是如何存储key和value的:
根结构为RedisServer,其中包含RedisDB(数据库)。而RedisDB实际上是使用Dict(字典)结构对Redis中的kv进行存储的。这里的key即字符串,value可以是string/hash/list/set/zset这五种对象之一。

Redis 大key如何处理?

Redis使用过程中经常会有各种大key的情况, 比如:
单个简单的key存储的value很大
hash, set,zset,list 中存储过多的元素(以万为单位)
由于redis是单线程运行的,如果一次操作的value很大会对整个redis的响应时间造成负面影响,所以,业务上能拆则拆,下面举几个典型的分拆方案。

业务场景:

即通过hash的方式来存储每一天用户订单次数。那么key = order_20200102, field = order_id, value = 10。那么如果一天有百万千万甚至上亿订单的时候,key后面的值是很多,存储空间也很大,造成所谓的大key。

大key的风险:

  1. 读写大key会导致超时严重,甚至阻塞服务。

  2. 如果删除大key,DEL命令可能阻塞Redis进程数十秒,使得其他请求阻塞,对应用程序和Redis集群可用性造成严重的影响。

redis使用会出现大key的场景:

  1. 单个简单key的存储的value过大;
  2. hash、set、zset、list中存储过多的元素。

解决问题:

  1. 单个简单key的存储的value过大的解决方案:

将大key拆分成对个key-value,使用multiGet方法获得值,这样的拆分主要是为了减少单台操作的压力,而是将压力平摊到集群各个实例中,降低单台机器的IO操作。

  1. hash、set、zset、list中存储过多的元素的解决方案:
    1).类似于第一种场景,使用第一种方案拆分;
    2).以hash为例,将原先的hget、hset方法改成(加入固定一个hash桶的数量为10000),先计算field的hash值模取10000,确定该field在哪一个key上。

将大key进行分割,为了均匀分割,可以对field进行hash并通过质数N取余,将余数加到key上面,我们取质数N为997。

那么新的key则可以设置为:

newKey = order_20200102_String.valueOf( Math.abs(order_id.hashcode() % 997) )
field = order_id
value = 10
hset (newKey, field, value) ;
hget(newKey, field)

大value数据是什么,会有怎样的问题?

当String类型的数据>10K,list、hash、set、sort set中元素个数超过1000时就可以被称为大value,当超过100K,或集合元素个数超过10000时可以被称为是超大value。大value最直接的影响就是有可能造成机器内存不足,就是数据倾斜;同时因为redis数据处理是单线程的,当value过大时,处理起来响应时间也会变慢。 常见的例子有:参与人数很多的盖楼活动或者很活跃的群聊消息列表等

怎么处理Redis大value?

大value的处理方式还是结合业务,对其进行拆分,将其数据分布在各个redis节点中,将操作压力平摊开,防止对单个实例IO或内存影响过大。

简单说一下 热点数据和大value的拆分,如果它是一个list、 set集合类型,比如原来的 为key value,value为list为拆为 list1 、list2、list3,那么新的key为 key+hash(list1)%10000 得到新的key,再对对应数据value进行set或get操作

如果是一个对象的json字符串,可以考虑将该对象的不同属性映射到不同hash槽从而分布在不同redis节点中;或者将不同属性拆分,利用hash结构进行存储,从而每次处理时仅获取一部分数据

相关文章:

【Redis】redis大key和大value的危害,如何处理?

前序 还记得上次和同事一起去面试候选人时,同事提了一个问题:Redis的大key有什么危害?当时候选人主要作答的角度是一个key的value较大时的情况,比如: 内存不均:单value较大时,可能会导致节点之…...

Spring Boot:实现MyBatis动态创建表

在有些应用场景中,我们会有需要动态创建和操作表的需求。 比如因为单表数据存储量太大而采取分表存储的情况,又或者是按日期生成日志表存储系统日志等等。这个时候就需要我们动态的生成和操作数据库表了。 而我们都知道,以往我们使用MyBati…...

SpringBoot+Seata在多数据源和feign中的简单使用

SpringBootSeata简单使用 目录seata执行过程安装seata下载seata使用自定义配置文件,NACOS为注册中心结合springboot实现AT模式1.多数据源引入依赖bootstrap.yml配置在使用的方法上用GlobalTransactional注解调用接口正常时调用接口报错时回滚2.配合feignseata优缺点seata执行过…...

计算机网络中的原码、反码、补码

写在前面 原码、反码、补码是计算机组成原理中的概念,是计算机网络的基础知识之一。这些概念是为了处理二进制数的符号位而引入的,常用于计算机中的整数运算,也常用于数据存储和传输等领域。因此,了解和掌握这些概念对于理解计算机…...

七、Bean的实例化方式

Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活) 第一种:通过构造方法实例化第二种:通过简单工厂模式实例化第三种&…...

Windows程序员学习Linux环境下VI(VIM)编辑器的使用方法

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows程序员如何学习Linux环境知识。由于很多程序在Windows环境下开发好后,还要部署到Linux服务器上去,所以作为Windows程序员有必要学习Linux环境的知识。VI…...

react入门篇

react入门篇前言一、目标二、项目环境三、实现过程(干货满满💥💥💥)1.创建react项目2.arco design UI库3.路由模块化4. 状态管理zustand5. axios6. 路由守卫前言 提示:这里可以添加本文要记录的大概内容&a…...

阿赵的MaxScript学习笔记分享九《可编辑多面体的操作》

大家好,我是阿赵。这是MaxScript学习笔记分享的第九篇,可编辑多面体的操作。不知不觉写了这么多篇了,应该还有几篇就写完了。自己给自己加一下油。 在3DsMax里面如果需要建模,一般使用到的塌陷方式有3种,可编辑的网格、…...

【Redis场景5】集群秒杀优化-分布式锁

集群环境下的秒杀问题 前序 【Redis场景1】用户登录注册 【Redis场景2】缓存更新策略(双写一致) 【Redis场景3】缓存穿透、击穿问题 【Redis场景拓展】秒杀问题-全局唯一ID生成策略 【Redis场景4】单机环境下秒杀问题 在单机环境下的并发问题,我们可以使用相关…...

transformer目标检测开山之作detr

1. 将一个batch的图片输入backone获得feature。 (2,c,w,h)先输入resnet50中,得到(2,2048,w,h)。虽然这里channel不是256,但是在输入e…...

双指针法|位运算|离散化|区间合并

目录 双指针算法 位运算 离散化 序列合并 双指针算法 题目描述&#xff1a;1.输入n个单词&#xff0c;每个单词在输入的时候按空格隔开&#xff0c;之后打印出每个单词且换行 #include<iostream> #include <string>using namespace std; int main() {strin…...

Rockchip Android13 GKI开发指南

Rockchip Android13 GKI开发指南 文章目录Rockchip Android13 GKI开发指南GKI介绍Google upstream kernel下载及编译Rockchip SDK中GKI相关目录介绍Rockchip GKI编译代码修改编译固件烧写KO编译及修改添加新的模块驱动的方法调试ko方法开机log确认uboot阶段Android阶段KO加载KO…...

手把手教你原生JavaScript打造丝滑流畅的轮播图,让你的网站瞬间提升用户体验!

简介 轮播图是网页设计中常见的交互组件之一&#xff0c;用于展示多张图片或内容&#xff0c;让用户能够方便地浏览、切换和选择。本文将介绍如何使用原生 JavaScript 手写一个简单的轮播图&#xff0c;并且通过代码解释实现细节。 目录 简介 HTML 结构 CSS 样式 JavaScr…...

git常用基本操作

克隆远程代码更新本地代码 git clone <-b | -branch> [branch name] [repository URL] git pull #拉取远程仓库代码&#xff0c;更新本地仓库 git merge <branch-name> #合并目标分支 建立本地仓库分支 git branch #查看当…...

剑指 Offer —— 数组和字符串

文章目录剑指 Offer 04. 二维数组中的查找代码实现解题方案 思路算法步骤剑指 Offer 05. 替换空格题目描述代码实现解题方案 思路算法步骤剑指 Offer 11. 旋转数组的最小数字 - 解决方案题目描述剑指 Offer 04. 二维数组中的查找 在一个 n * m 的二维数组中&#xff1a; 每…...

Java 字符编码

编码&#xff1a;数据存储进计算机中需要转换为二进制存储&#xff0c;这个过程就是编码。 解码&#xff1a;计算机读取数据并展示在页面上&#xff0c;需要将二进制转换为人类语言的过程&#xff0c;叫做解码。 乱码&#xff1a;如果编码和解码时使用的码表不一样&#xff0c;…...

ubuntu-9-安装chrony时间同步

使用chrony搭建时间同步服务器 [Linux系列]Chrony时间同步服务器 配置chrony服务&#xff0c;实现服务器时间自动同步 linux上内网环境配置NTP时间同步详解 经验体会&#xff1a;解决Ubuntu 18.04Windows双系统时间不同步的问题 1 时间同步 我们知道一台电脑主机&#xff0c;…...

CMMI流程规范—服务与维护

服务与维护&#xff08;Service and Maintenance, SM&#xff09;是指产品销售之后的客户服务和产品维护。客户服务和产品维护的宗旨就是提高客户对产品以及对开发方的满意度。服务与维护过程域是SPP模型的重要组成部分。本规范阐述了服务与维护过程域的两个主要规程&#xff1…...

【蓝桥杯集训12】DFS(3 / 5)

目录 842. 排列数字 - DFS按位置枚举 843. n-皇后问题 - DFS按行枚举 165. 小猫爬山 - DFS枚举小猫 1209. 带分数 - DFS 3502. 不同路径数 - 842. 排列数字 - DFS按位置枚举 活动 - AcWing 题目&#xff1a; 给你一个整数n 要求将1~n的所有排列情况列出 比如&#xff1a…...

Elasticsearch:构建自动补全功能 - Autocomplete

什么是自动补全&#xff08;autocomplete&#xff09;功能呢&#xff1f;我们举一个很常见的例子。 每当你去谷歌并开始打字时&#xff0c;就会出现一个下拉列表&#xff0c;其中列出了建议。 这些建议与查询相关并帮助用户完成查询。 Autocomplete 正如维基百科所说的&#xf…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...