Redis高级篇——Redis的优化

news/2024/5/2 23:22:23/文章来源:https://blog.csdn.net/qq_52595134/article/details/128111806

一、Redis的键值设计

1.1key的结构

Redis的Key在自定义时,最好遵循以下三个规则:

  • 基本格式:[业务名称]:[数据名]:[id]
  • 长度不超过44字节
  • 不包含特殊字符

如:登录业务,保存用户信息的key 定义为 login:user:10( [业务名称]:[数据名]:[id] )

优点:

  • 可读性强

  • 避免key冲突

  • 方便管理(使用可视化工具显示的是 层级结构 清晰明了)

  • 更节省内存:key是string类型,底层编码包含int、embstr和raw三种。embstr在小于44字节使用,采用连续内存空间,内存占用更小

1.2 BigKey问题

BigKey通常以key的大小和key中成员的数量来综合判定,如:

  • key本身的数据量过大:一个string类型的key,它的值为5MB
  • key中成员数过多:一个ZSET类型的key,它的成员数量为10000个
  • key中成员的数据量过大:比如一个Hash类型的key,它的成员数量可能不多,但是每个成员的value数据量大

推荐值:

  • 单个key的value小于10KB
  • 对于集合类型的key,建议元素数量小于1000

1.BigKey的危害

  • 网络阻塞
    对BigKey执行读请求时,少量的QPS就可能导致带宽使用率被占满,导致Redis实例甚至物理机变慢

  • 数据倾斜
    BigKey所在的Redis实例内存使用率远超其他实例,无法使数据分片的内存资料达到均衡

  • Redis阻塞
    对元素较多的hash、list、zset等做运算会耗时较久,使主线程被阻塞

  • CPU压力
    对BigKey的数据序列化和反序列化会导致CPU的使用率飙升,影响Redis实例和本机其他应用

2.查找BigKey

  • redis-cli -a 密码 --bigkeys
    利用redis客户端提供的参数,可以遍历分析所有的key,并返回key的整体统计信息与每个数据类型的Top1 的big key
    在这里插入图片描述
    (每种数据类型的Top1可能是bigKey也可能不是,因为可能这种数据类型的key使用的数量少,而一些使用频率高的数据类型可能Top2也是BigKey,因此统计的并不完整)

  • scan
    自己编程,利用scan扫描Redis中的所有key,利用strlen、hlen等命令判断key的长度
    在这里插入图片描述scan 是对所有key分成多个部分进行扫描,避免在千万数量级key下 扫描所有key 影响主线程性能

  • 第三发工具
    利用第三方工具,如Redis-Rdb-Tools分析RDB快照文件,全面分析内存使用情况

  • 网络监控
    自定义工具,监控Redis的网络数据,超出预警值时主动告警 (一般使用云服务中的工具分析如:阿里云)

3.删除BigKey

使用 unlink 异步删除 (Redis 4.0以后)
在这里插入图片描述

4.避免BigKey

例1: 比如在存储一个User对象,有三种存储方式:
在这里插入图片描述
由图可知,当存储User对象这类数据时,最好选择hash结构进行存储,空间占用小,且可以灵活访问对象的任意字段(hash结构存储注意数据类型转化)

例2: 假如hash类型的key,有100万对field和value,这个key有什么问题?如何优化?
在这里插入图片描述

存在的问题:

  1. hash的entry数量超过500时,会使用哈希表而不是ZipList,内存占用多
  2. 可以通过hash-max-ziplist-entries配置entry上限。但是如果entry过多就会导致BigKey问题

在这里插入图片描述
string类型占用内存太高,且批量获取数据麻烦,没有hash结构的关联性

在这里插入图片描述

注: 一些短期使用的key或者不经常使用的key设置过期时间,这样就不会出现BigKey问题

二、批处理优化

2.1 Pipeline

1.批处理的优势
单个命令的执行流程

一次命令的响应时间 = 1次往返的网络传输耗时+1次Redis执行命令耗时
在这里插入图片描述

网络传输耗时: ms毫秒级别 Redis执行命令耗时:us微秒级别
如果执行N条命令,那么N次网络传输往返的耗时将被扩大N倍,而执行命令的耗时可以忽略不记,此时执行N条命令耗时很长,会影响Redis的性能

如果一次网络传输就执行N次命令,那么就可以解决批量数据操作耗时长问题,提高了效率
在这里插入图片描述

Redis提供了很多批处理命令,可以实现批量插入数据,例如:

  • mset
  • hmset

注: 不要在一次批处理中传输太多命令,否则单次命令占用带宽过多,会导致网络阻塞

由于mset只能对string类型的数据进行批处理,而hmset只能对hash类型的数据进行操作,如果对复杂数据类型处理可以使用 Pipeline

Pipeline类似于一个管道,将命令放入管道中进行传输。
在这里插入图片描述

Pipeline的多个命令之间不具备原子性,可能会出现多线程插队等待耗时问题。

2.2 集群下的批处理

mset 或Pipeline这样的批处理需要在一次请求中携带多条命令,而此时如果Redis是一个集群,那批处理命令的多个key必须落在一个插槽中,否则就会导致执行失败。

解决方案:
在这里插入图片描述
由于hash_tag容易出现数据倾斜,在集群模式下数据倾斜可能会造成单点问题,因此常用并行slot方式实现集群下批处理。在spring整合的redis包中 stringRedisTemplate 有封装好的用法,底层实现时异步的管道传输模式。
例如:stringRedisTemplate.opsForValue().multiSet();

三、服务端优化

3.1持久化配置

Redis的持久化虽然保证数据安全,但也会带来很多额外的开销,因此持久化一般遵守以下建议:

  1. 用来做缓存的Redis实例尽量不要开启持久化功能 (开多个Redis实例分别复杂不同的业务)
  2. 建议关闭RDB持久化功能,使用AOF持久化
  3. 利用脚本定期在slave节点做RDB,实现数据备份
  4. 设置合理的rewrite阈值,避免频繁的bgrewrite
  5. 配置no-appendfsync-on-rewrite = yes,禁止在rewrite期间做AOF,避免因AOF引起的阻塞 (可能出现数据丢失)
    Redis持久化详情

部署相关建议:

  1. Redis实例的物理机要预留足够内存,应对fork和rewrite
  2. 单个Redis实例内存上限不要太大,例如4G或8G。可以加快fork的速度、减少主从同步、数据迁移压力
  3. 不要与CPU密集型应用部署在一起 (fork时比较耗CPU)
  4. 不要与高硬盘负载应用一起部署。例如:数据库、消息队列

总结就是 redis最好独占一个服务器 hh

3.2 慢查询

在Redis执行时耗时超过某个阈值的命令,称为慢查询。
由于Redis是单线程执行命令,所以执行一个命令会放入队列中,排队等待执行,此时若一个慢查询耗时较久,队列中等待的命令可能因等待超时出错
在这里插入图片描述
阈值 的配置:

  • slowlog-log-slower-than :慢查询阈值,单位微秒。默认10000,建议1000
    慢查询会被放入慢查询日志中,日志的长度有上限,可以通过配置指定:
  • slowlog-max-len: 慢查询日志(本质是一个队列)的长度。默认是128,建议1000
    在这里插入图片描述
    查看慢查询日志列表:
  • slowlog len : 查询慢查询日志长度
  • slowlog get [n] 读取n条慢查询日志
  • slowlog reset:清空慢查询列表

在这里插入图片描述
可以使用桌面客户端RESP
在这里插入图片描述

3.3 内存安全和配置

当Redis内存不足时,可能导致key频繁被删除、响应时间变长、QPS不稳定等问题。当内存使用率达到90%以上时就需要警惕,并快速定位到内存被占用的原因。
在这里插入图片描述
查看Redis目前的内存分配状态

  • info memory
  • memory xxx

内存缓冲区配置

  • 复制缓冲区:主从复制的repl_backlog_buf,如果太小可能导致频繁的全量复制,影响性能。通过repl-backlog-size来设置,默认1mb
  • AOF缓冲区:AOF刷盘之前的缓存区域,AOF执行rewrite的缓冲区。无法设置容量上限
  • 客户端缓冲区:分为输入缓冲区和输出缓冲区,输入缓冲区最大1G且不能设置。输出缓冲区可以设置
    在这里插入图片描述

3.4 集群的问题

1.数据完整性问题
在Redis的默认配置中,如果发现任意一个插槽不可用,整个集群都会对外停止服务
在这里插入图片描述

2.带宽问题
集群节点之间会不断的互相Ping来确定集群中其它节点的状态。每次Ping携带的信息至少包括:

  • 插槽信息
  • 集群状态信息

集群中节点越多,集群状态信息数据量也越大,10个节点的相关信息可能达到1kb,此时每次集群互通需要的带宽会非常高。

解决途径:

  1. 避免大集群,集群节点数不要太多,最好少于1000,如果业务庞大,则建立多个集群。
  2. 避免在单个物理机中运行太多Redis实例
  3. 配置合适的cluster-node-timeout

3.数据倾斜问题

BigKey或批处理时,使用相同的hash_tag来保证所有key落在同一个插槽slot,会导致某些结点数据量远大于其他节点

4.客户端性能问题
当使用客户端连接Redis集群时,需要进行节点选择、插槽slot判断、读写判断,会影响客户端性能

5.命令的集群兼容性问题

比如批处理 mset 在集群模式如果不能落在相同的插槽slot上就会报错。

6.lua和事务问题
多个命令的key必须在同一个slot,如果不在就会报错。因此集群模式下就不能使用lua和事务

单体Redis(主从Redis)已经能达到万级别的QPS,并且也具备很强的高可用性。如果主从能满足业务需求,那么就尽量不搭建Redis集群

参考学习:黑马Redis入门到实战

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

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

相关文章

python常用代码总结2

1、列表的常规追加元素、追加列表操作 (1)列表追加多个元素,比如追加0-9 ls [] ls.extend(list(range(10)))ls Out[20]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (2)列表追加多个相同的元素,比如追加10个0 ls1 [] for i in range(10):ls1.append(0)ls1 Ou…

直播邀请函 | 第12届亚洲知识产权营商论坛:共建创新价值 开拓崭新领域

由香港特别行政区政府、香港贸易发展局及香港设计中心共同举办的亚洲知识产权营商论坛,每年为世界各地知识产权业界专家、商界领袖提供一个理想平台,共同探讨亚洲知识产权市场的最新发展,发掘更多商机。 去年,论坛共邀请70余位国…

聚观早报 | 中国茶申遗成功;特斯拉市值蒸发4个推特

今日要闻:中国茶申遗成功;特斯拉市值蒸发4个推特;iPhone14Pro出货量预期下调;FF91距交付仅剩一步之遥;AI绘画一天新增60万用户中国茶申遗成功 11月29日晚,我国申报的“中国传统制茶技艺及其相关习俗”在摩洛…

[附源码]JAVA毕业设计高速公路服务区管理系统(系统+LW)

[附源码]JAVA毕业设计高速公路服务区管理系统(系统LW) 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项…

最全面的Spring教程(五)——文件上传与下载

前言 本文为 【SpringMVC教程】文件上传与下载 相关知识&#xff0c;具体将对使用MultipartResolver处理文件上传的步骤&#xff0c;两种文件下载方式&#xff08;直接向response的输出流中写入对应的文件流、使用 ResponseEntity<byte[]>来向前端返回文件&#xff09;等…

智慧城市运营中心建设方案(SCOC)智慧城市的心脏

一、大数据&#xff1a;智慧城市的基础与引擎 中国每天正以消失100个村庄的速度快速步入城镇化&#xff0c;未来10年内将有5亿以上的人涌入城市。这无疑会给城市的建设带来巨大的压力&#xff0c;城市资源有限&#xff0c;规模不可能无限扩张&#xff0c;城市在就业、教育、住房…

HashMap底层数据结构,扩容机制

HashMap的底层结构是数组链表 没有哈希冲突的元素放在数组里面&#xff0c; 哈希冲突的元素用链表串起来 初始数组长度是16&#xff0c;对应源码&#xff1a; static final int DEFAULT_INITIAL_CAPACITY1; 最大的容量为2的30次方&#xff0c;一个很大很大很大的数 还定义了…

多个JDK版本可以吗:JDK17、JDK19、JDK1.8轻松切换(无坑版)小白也可以看懂

多个版本JDK切换 多个JDK&#xff1a;JDK17、JDK19、JDK1.8轻松切换&#xff08;无坑版&#xff09;小白也可以看懂 提示&#xff1a;看了网上很多教程&#xff0c;5w观看、32w观看、几千观看的&#xff0c;多多少少带点坑&#xff0c;这里我就把踩过的坑都给抹了 文章目录多个…

【数据结构】二叉树的运算

********************************************************************************************************* 本文作者科大MF22某班Noah懒羊羊同学&#xff0c;为大家提供一个作业思路&#xff0c;请勿直接copy&#xff01;&#xff01;&#xff01;一起进步学习~ ******…

极值分析:分块极大值BLOCK-MAXIMA、阈值超额法、广义帕累托分布GPD拟合降雨数据时间序列...

全文链接&#xff1a;http://tecdat.cn/?p25348 你们可能知道&#xff0c;实际极值分析有两种常用方法&#xff1a;分块极大值Block-maxima、阈值超额法threshold excess&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。今天&#xff0c;我们将分别介绍这两种…

【毕业设计】10-基于单片机的车站安检门_磁性霍尔传感器系统设计(原理图+源码+仿真工程+答辩论文)

【毕业设计】10-基于单片机的车站安检门/磁性霍尔传感器系统设计&#xff08;原理图源码仿真工程答辩论文&#xff09; 文章目录【毕业设计】10-基于单片机的车站安检门/磁性霍尔传感器系统设计&#xff08;原理图源码仿真工程答辩论文&#xff09;任务书设计说明书摘要设计框架…

【数据结构】Java实现数据结构的前置知识,时间复杂度空间复杂度,泛型类的讲解

文章目录数据结构时间复杂度、空间复杂度包装类、装箱与拆箱泛型擦除机制数据结构 当我们在成为一名程序员的这条道路上努力的时候&#xff0c;我们一定经常听到这个词数据结构。那么究竟什么是数据结构呢&#xff1f;数据结构顾名思义&#xff0c;就是数据结构&#xff0c;数…

【深度学习】详解 CLIP

目录 摘要 一、引言和激励性工作 二、方法 2.1 自然语言监督 2.2 创建一个足够大的数据集 2.3 选择一种有效的预训练方法 2.4 选择和放缩一个模型 2.5 训练 三、实验 3.1 零次迁移 3.1.1 激励 Github&#xff1a;GitHub - openai/CLIP: Contrastive Language-Image …

Android 导航之Navigation 组件的介绍与使用

1、介绍&#xff1a; 在以前的应用中&#xff0c;针对多导航模块的使用&#xff0c;常见的有tabhost或者FragmentTabHost&#xff0c;但是这些在使用的过程中&#xff0c;非常臃肿&#xff0c;包括加载和管理也不如人意。在AndroidX中&#xff0c;官方引入Navigation模块&#…

Spring | IOC技术之Bean的配置与实例化

&#x1f451; 博主简介&#xff1a;    &#x1f947; Java领域新星创作者    &#x1f947; 阿里云开发者社区专家博主、星级博主、技术博主 &#x1f91d; 交流社区&#xff1a;BoBooY&#xff08;优质编程学习笔记社区&#xff09; 文章目录Bean的基础配置1、id 与 cla…

Anaconda默认安装在C:\Users\xxx\.conda\envs中

目录 问题&#xff1a; 解决&#xff1a; 更改默认安装位置 移动已安装环境 问题&#xff1a; 解决&#xff1a; 更改默认安装位置 用记事本打开 C:\Users\zqk\.condarc 在最后插入 envs_dirs: - D://anzhuang//Anaconda3//envs 如若需更改pkgs&#xff0c;插入如下代…

OTA: Optimal Transport Assignment for Object Detection 原理与代码解读

paper&#xff1a;OTA: Optimal Transport Assignment for Object Detection code&#xff1a;https://github.com/Megvii-BaseDetection/OTA 背景 标签分配&#xff08;Label Assignment&#xff09;是目标检测中重要的一环&#xff0c;经典的标签分配策略采用预定义的规则…

Caffeine 源码、架构、原理(史上最全,10W字 超级长文)

文章很长&#xff0c;而且持续更新&#xff0c;建议收藏起来&#xff0c;慢慢读&#xff01;疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 &#xff1a; 免费赠送 :《尼恩Java面试宝典》 持续更新 史上最全 面试必备 2000页 面试必备 大厂必备 涨薪必备 免费赠送 经典…

【剧前爆米花--爪哇岛寻宝】面向对象的三大特性——封装、继承以及多态的详细剖析(中——多态)。

作者&#xff1a;困了电视剧 专栏&#xff1a;《JavaSE语法与底层详解》 文章分布&#xff1a;这是一篇关于Java面向对象三大特性——多态的文章&#xff0c;在本篇文章中我会分享多态的一些基础语法以及类在继承时代码的底层逻辑和执行顺序。 目录 多态的定义及实现条件 多态…

【程序人生】4年创作纪念日,不忘初心,继续前行

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码&#xff0c;就职于大型金融公司后端高级工程师&#xff0c;擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…