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

Redis Scan代替Keys优化

接手的项目破破烂烂,总是让我修修补补——生无可恋的程序员。

事情大概是这样,接手了这个项目后,发现线上经常出现Broken pipe异常,查了一下,大概意思就是客户端等待服务端过程中超时了,后来连接被复用时发现已关闭。最终定位是请求redis导致的程序被hang住,然后发现redis没有配置超时时间,于是配了超时,但是没有解决请求redis超时的问题,线上开始出现大量redis超时的异常。

对于redis的超时,首先查了下redis上的慢查询日志,发现有大量的执行keys命令的记录,排查代码,发现了这部分keys的来源,业务逻辑是每分钟统计一次活跃用户数,每一个用户在redis中以一个key保存,key的结构是"前缀:用户ID"这个样子。keys命令查询的就是符合"前缀:*"格式的所有缓存数据。有职业素养的大家,一定都被教育过,不要在生产环境使用keys命令。或者,至少大家应该都背过这个八股。所以,解决方案呼之欲出,用scan替换keys。

新增的scan方法代码如下:

public Set<String> scan(String matchKey) {Set<String> keys = redisTemplate.execute((RedisConnection connection) -> {Set<String> keySet = new HashSet<>();//定义起始游标,获取lettuce原生引用,定义scan参数ScanCursor scanCursor = ScanCursor.INITIAL;RedisKeyAsyncCommands commands = (RedisKeyAsyncCommands) connection.getNativeConnection();ScanArgs scanArgs = ScanArgs.Builder.limit(1000).match(matchKey + "*");try {do {//最少scan一次,当返回不为空时将扫描到的key添加到统一key列表中KeyScanCursor<byte[]> keyScanCursor = (KeyScanCursor) commands.scan(scanCursor, scanArgs).get();if (keyScanCursor != null) {if (!CollectionUtils.isEmpty(keyScanCursor.getKeys())) {keyScanCursor.getKeys().forEach(b -> keySet.add(new String(b)));}scanCursor = keyScanCursor;} else {scanCursor = ScanCursor.FINISHED;}} while (!scanCursor.isFinished());} catch (Exception e) {log.error("redisClient scanKey fail patternKey:[{}]", matchKey, e);}return keySet;});return keys;}

参考文献

SpringBoot中RedisCluster的scan命令实践-阿里云开发者社区

 

http://www.xdnf.cn/news/610921.html

相关文章:

  • 2025国内领先GEO服务商上海源易:AI赋能下的GEO内容创新与实践
  • Linux iSCSI存储共享实验指南
  • NFS服务小实验
  • SkyWalking启动失败:OpenSearch分片数量达到上限的完美解决方案
  • c语言字符串函数
  • 深入浅出 Python Testcontainers:用容器优雅地编写集成测试
  • Java详解LeetCode 热题 100(20):LeetCode 48. 旋转图像(Rotate Image)详解
  • 皮尔森电流互感器在浪涌电流测试中的应用
  • 如果教材这样讲---开关电源的拓扑结构
  • 路由协议RIP配置与分析
  • 现代软件开发利器
  • C++成员对象和封闭类
  • 【鼎的3D设计与AI提示词方案】
  • echarts之双折线渐变图
  • 独木桥 Java
  • 基于SpringBoot+Vue的社区医院信息平台设计与实现
  • 软考中级软件设计师——计算机系统篇
  • STM32+腾讯物联网平台OTA升级详细教程
  • 华为OD机试_2025 B卷_爱吃蟠桃的孙悟空(Python,100分)(附详细解题思路)
  • 从逆流监测到智慧用电:ADL200N-CT系列单相导轨表赋能家庭绿色能源
  • ubuntu设置开机不输密码笔记
  • 解决Vue项目依赖错误:使用electron-vite重建
  • 提升开发运维效率:原力棱镜游戏公司的 Amazon Q Developer CLI 实践
  • 使用clickhouse的ReplacingMergeTree引擎表做活跃玩家信息表
  • Unity 打包程序全屏置顶无边框
  • 宽松相等(==) 的转换规则(仅考虑基本数据类型)
  • 怎么判断一个Android APP使用了Ionic这个跨端框架
  • 智能交通红绿灯系统(Python)
  • TCP 三次握手,第二次握手报文丢失会发生什么?
  • IP隧道技术中数据包头部的变化分析:必然增加的封装机制