Redis常见的一些问题和注意事项

        本文汇总的都是在我们公司出现过的常见问题以及自己曾经记录的注意事项。

        我们公司sentinel模式以及RedisCluster集群两种部署方式都有使用,下面问题有些可能是哨兵模式下存在的,比如批量操作,下面可能不会特别说明。

1、注意热点key

        之前单位有一个实际案例是某个系统的交易成功率低于最低告警值 ,其产生原因就是Redis存在两个热点key,且这两个key都在同一个master节点上(RedisCluster集群),导致在高峰期间对应节点访问流量过大,造成了严重的访问倾斜。

        对于这种问题,我们可以通过两种方式解决。

        1、增加一层本地缓存,减少Redis的访问,基本上多级缓存都这么干;

        2、考虑到一致性的问题,用不了本地缓存,像秒杀场景的活动库存这种,就可以将热点key分散存储,一个key拆成多个子key存储。比如某电商进行茅台抢购活动,首先将茅台商品活动库存放到Redis中,茅台就是一个热点key,如maotai,1000,此时就可以将热点key分散存储,茅台抢购是需要预约的,可以将所有预约用户进行分组,Redis会根据组存储活动库存,key可以是 maotai:groupId1 300,maotai:groupId2 300,maotai:groupId3 400,通过这种方式把整个流量分散到不同的节点上,减轻单节点压力。

        当然,有人会问,那出现有些节点抢购完了,有些没抢购完怎么办?对于这个问题,首先是我们用户都是平均hash到不同的节点上的,请求总体上是平均的;其次就算是出现了这种情况,对于抢购这种营销活动,我们是允许少卖的,超卖却是不可以,同样因为性能降低导致系统崩溃也是不允许的。总结说就是我们要做到两权相害取其轻。

 

2、避免bigKey

        另一个实际案例同样是某系统的交易超时和成功率低预警,以及机房传输设备有端口心跳告警,其产生原因是存在bigKey,且进行批量操作(hgetall,hsetall),在交易并发量增大时,批量查询存储操作对Redis性能影响较大,查询缓慢进而导致交易超时。

       尽管Redis在Redis4.0引入了后台多线程,Redis6又引入了IO多线程,但Redis的主要命令执行依然是单线程的。如果对单个key进行批量操作,如hashKey的 hgetall,hsetall,执行的时间复杂度是O(N),当并发上来的时候,这种操作是非常低效的,很容易造成客户端阻塞。此外也可能会引发网络阻塞。因为每次获取大 key 产生的网络流量较大,举一个极端的例子,一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说比较难以承受。

  我在之前写的文章已经详细说了这个问题以及解决办法,传送门:

Redis的big key问题介绍以及监控手段icon-default.png?t=N7T8https://blog.csdn.net/hbnn111/article/details/135969182

3、在使用lettuce时,记得配置网络拓扑刷新

       在Java领域,Redis客户端还是比较多的,如jedis,redisson,lettuce等,Springboot2.x以后默认是lettuce,由于其高性能以及并发安全性使其得到了很广泛的使用,但其有一个最大的弊端是默认不进行网络拓扑刷新。那啥是网络拓扑刷新呢?即RedisCluster集群,如果某个master节点异常宕机,集群会自动进行重新选主,某个slave会被选举成为master,然而lettuce客户端默认并不会感知,导致请求还会达到不可达的节点上,从而出现超时,严重的会因为连接池的限制影响到其他正常的master请求。

        springboot2.3以后lettuce可以进行网络拓扑刷新配置:

spring:redis:lettuce:cluster:refresh:adaptive: trueperiod: 10000    # 10秒自动刷新一次

        如果不想用lettuce,可以切换成jedis或者Redisson都可以,这两者都默认实现了网络拓扑刷新。        

        这个问题在我前东家和现在的公司都出现过,前公司的解决方案是直接把客户端换成jedis,现在的解决方式就是配置网络拓扑刷新。

4、使用Redis客户端,根据实际情况配置连接池

        这个和数据库连接池是一致的,主要是配置最小空闲连接和最大空闲连接,min-idle和max-idel,这两个配置不是一拍脑门就决定的,而是要根据业务的实际情况不断去调试,这和所有的池化原理都一样,如连接池,线程池都要根据业务调优。

        连接池的问题在jedis上更为突出,因为lettuce采用了Netty,使用了多线程+IO多路复用+异步的并发方式,性能上比jedis更好,jedis非常容易因为某些请求长时间占用线程导致连接池耗尽。因此目前生产上出现Redis连接池问题的基本上都是jedis客户端引起的,我们单位出现的几起事故都是。当然,这并不是绝对啊,lettuce同样有出现问题的可能。

        

5、尽量避免大量使用批量操作

        批量操作可能大家用的比较多,因为可以减少请求次数,但用多了同样是会出现问题的,如果频繁的进行批量操作,由于Redis是单线程的,其他命令就会阻塞住,如果批量操作比较耗时的话,就将是灾难性的。

        

6、生产环境禁用的命令

    • keys * :排在首位, 重中之重,用了它,Redis就完蛋了,很有可能导致整个集群出现大面积故障
    • flushall: 同步操作
    • flushdb: 同步操作,丢失当前database的所有数据,出现堵死现象
    • save: 同步操作
    • bgsave: 尽管是异步操作,但需要同步fork子线程,FORK引起COW内存消耗,有导致大面积OOM的风险。这个主要还是Redis自己执行就OK了,不需要我们操作
    • shutdown: 导致Redis关闭、数据丢失和故障转移
    • debug : 导致Redis Crash、堵死和集群故障转移等

7、Key的设计规范

    • Redis缓存场景,建议Key都设置TTL值,保证不使用的Key能被及时清理或淘汰,使内存复用。
    • 建议Key使用":"字符进行分层,如 hbnnmall:coupoun:uid。
    • Key名字本身是String对象,最大长度512MB,也是big key的范畴。
    • Key的长度小于30个字符,Key内容本身分占用1到多份内存容量。
    • 按业务功能命名key前缀,防止key冲突覆盖,同时方便运维管理。

8、程序架构规范

  • 查看命令时间复杂度,官方文档Commands,每个都对应有Time complexity属性;如HGETALL命令Time complexity: O(N) where N is the size of the hash.时间复杂度为O(N)的常见命令: keys mget mset hgetall。

  • redis是single-threaded server,如果命令耗时过长,命令独占server,其间不能响应其他命令,导致服务超时。如果执行时间比较长,甚于导致判断节点为下线状态,触发集群故障转移。
  • 避免使用时间复杂度为O(N)的访问模式或命令;对元素比较多的集群key使用时间复杂度为O(N)命令。
  • Cluster模式中,热点Key和大容量Key尽量设计"打散”;避免集群不均,导致某个分片QPS“过载“和容量过大。

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

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

相关文章

Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066

很奇怪的问题,在使用nifi的时候碰到的,这里是用NIFI,把数据从postgresql中同步到mysql中, 首先postgresql中的源表,中是没有create_time这个字段的,但是同步的过程中报错了. 报错的内容是说,目标表中有个create_time字段,这个字段是必填的,但是传过来的flowfile文件中,的数据没…

轻松驾驭工作流:低代码开发平台一键回退,流程错误无处遁形

流程回退规则配置 说明 通常业务场景,当我们流程节点开启回退功能后,可根据业务需求设置不同节点自定义回退到哪一节点。如某一节点审批人可以直接退到发起人节点,另外节点审批人又可以回退到另外节点或者是范围内等等,这些都是…

001集——在线网络学习快速完成——16倍速度

在线网络学习快进方法如下: 电脑下载 Microsoft edge 浏览器,有的电脑是自带的 1、点击右上角… 2、点击"扩展" 3、点击"管理扩展" 4、点击"获取 Microsoft edge 扩展" 5、搜索框里搜" global " 6、获取"…

基于SpringBoot+uniapp的兼职众包系统小程序众包软件源码

项目背景 在数字化浪潮的推动下,兼职众包行业正在迅速崛起,成为灵活就业市场的新宠。兼职众包系统软件与平台以其高效、便捷的特点,吸引了越来越多的用户和企业。在数字化时代,兼职众包平台作为连接灵活劳动力与需求方的桥梁&…

【电路笔记】-逻辑非门

逻辑非门 文章目录 逻辑非门1、概述2、晶体管逻辑非门3、六角施密特反相器逻辑非门是所有逻辑门中最基本的,通常称为反相缓冲器或简称为反相器。 1、概述 反相非门是单输入器件,其输出电平通常为逻辑电平“1”,当其单个输入为逻辑电平“1”时,输出电平变为“低”至逻辑电平…

微软文本转语音和语音转文本功能更新,效果显著!

今天我要和大家分享一个新功能更新——微软的文本转语音和语音转文本功能。最近,微软对其AI语音识别和语音合成技术进行了重大升级,效果非常好,现在我将分别为大家介绍这两个功能。 先来听下这个效果吧 微软文本转语音和语音转文本功能更新 …

Vscode连接WSL2当中的jupyter

主要解决办法参考自这篇博客 1. 在WSL当中安装jupyter 这个随便找一篇博客即可,比如这篇,也可以根据现有的环境参考其它博客内容 2. 使用jupyter创建一个虚拟环境 首先激活想要添加的虚拟环境后,输入命令安装库: pip install ipykernel …

JavaScript - 你知道Ajax的原理吗?如何封装一个Ajax

难度级别:中高级及以上 提问概率:75% 想要实现Ajax,就需要创建它的核心通信对象XMLHttpRequest,通过核心对象的open方法与服务端建立连接,核心对象的send方法可以将请求所需数据发送给服务端,服务端接收到请求并做出响应,我们通过核心对象…

代码+视频,手动绘制logistic回归预测模型校准曲线(Calibration curve)(2)

校准曲线图表示的是预测值和实际值的差距,作为预测模型的重要部分,目前很多函数能绘制校准曲线。 一般分为两种,一种是通过Hosmer-Lemeshow检验,把P值分为10等分,求出每等分的预测值和实际值的差距 另外一种是calibrat…

项目设计方案:市交通视频监控平台项目设计方案(四)

目录 1 前言 1.1 目的 1.2 适用范围 1.3 术语表 2 现状分析 2.1 业务现状 2.2 组织机构现状 2.3 存在的问题 2.4 项目成果预期 3 系统建设原则 4 项目需求 4.1 项目需求 4.1.1 业务需求主要分为三部分: 4.1.2 技术需求主要分为四部分: 4.…

实验笔记之——Gaussian-SLAM测试与配置

之前博客对基于3DGS的SLAM进行了调研 学习笔记之——3D Gaussian Splatting及其在SLAM与自动驾驶上的应用调研_3d gaussian splatting slam-CSDN博客文章浏览阅读4.6k次,点赞49次,收藏82次。论文主页3D Gaussian Splatting是最近NeRF方面的突破性工作&a…

FJSP:美洲狮优化算法(Puma Optimizar Algorithm ,POA)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题(Flexible Job Shop Scheduling Problem,FJSP),是一种经典的组合优化问题。在FJSP问题中,有多个作业需要在多个机器上进行加工,每个作业由一系列工序组成&a…