获取平台Redis各项性能指标
业务场景
在XXXX项目中把A网的过车数据传到B网中,其中做了一个业务处理,就是如果因为网络或者其他原因导致把数据传到B网失败,就会把数据暂时先存到redis里,并且执行定时任务重新发送失败的。
问题
不过现场的情况比较不稳定。出现问题的原因是XX平台的云存储突然崩掉,技术与总部云存储研发的同事花了较长的时间,最后才把平台重新恢复,在此期间由于无法从云存储中读取图片导致发送过车数据失败,且柳州每日车流量较大。最后导致平台的redis积压了大量数据,而平台其他组件也需要依赖redis,进而影响整个平台的运行。
解决方案
在存储数据前读取redis里的数据占用率百分比,然后配置文件里有个给我们配置的数值,如果redis里实际的占用率超过设置的这个数值,每当放入一条新的数据就会去除一条最旧的数据。若没有超过这个设置值,则按正常存入redis。
下面是把大多可能需要用到的性能指标封装到一个实体类里
RedisInfo
public class RedisInfo {private static Map<String, String> map = new HashMap<>();static {map.put("redis_version", "Redis 服务器版本");map.put("redis_git_sha1", "Git SHA1");map.put("redis_git_dirty", "Git dirty flag");map.put("os", "Redis 服务器的宿主操作系统");map.put("arch_bits", " 架构(32 或 64 位)");map.put("multiplexing_api", "Redis 所使用的事件处理机制");map.put("gcc_version", "编译 Redis 时所使用的 GCC 版本");map.put("process_id", "服务器进程的 PID");map.put("run_id", "Redis 服务器的随机标识符(用于 Sentinel 和集群)");map.put("tcp_port", "TCP/IP 监听端口");map.put("uptime_in_seconds", "自 Redis 服务器启动以来,经过的秒数");map.put("uptime_in_days", "自 Redis 服务器启动以来,经过的天数");map.put("lru_clock", " 以分钟为单位进行自增的时钟,用于 LRU 管理");map.put("connected_clients", "已连接客户端的数量(不包括通过从属服务器连接的客户端)");map.put("client_longest_output_list", "当前连接的客户端当中,最长的输出列表");map.put("client_longest_input_buf", "当前连接的客户端当中,最大输入缓存");map.put("blocked_clients", "正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量");map.put("used_memory", "由 Redis 分配器分配的内存总量,以字节(byte)为单位");map.put("used_memory_human", "以人类可读的格式返回 Redis 分配的内存总量");map.put("used_memory_rss", "从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致");map.put("used_memory_peak", " Redis 的内存消耗峰值(以字节为单位)");map.put("used_memory_peak_human", "以人类可读的格式返回 Redis 的内存消耗峰值");map.put("used_memory_lua", "Lua 引擎所使用的内存大小(以字节为单位)");map.put("used_memory_dataset_perc", "数据占用的内存大小的百分比");map.put("mem_fragmentation_ratio", "sed_memory_rss 和 used_memory 之间的比率");map.put("mem_allocator", "在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc");map.put("redis_build_id", "redis_build_id");map.put("redis_mode", "运行模式,单机(standalone)或者集群(cluster)");map.put("atomicvar_api", "atomicvar_api");map.put("hz", "redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,程序规定serverCron每秒运行10次。");map.put("executable", "server脚本目录");map.put("config_file", "配置文件目录");map.put("client_biggest_input_buf", "当前连接的客户端当中,最大输入缓存,用client list命令观察qbuf和qbuf-free两个字段最大值");map.put("used_memory_rss_human", "以人类可读的方式返回 Redis 已分配的内存总量");map.put("used_memory_peak_perc", "内存使用率峰值");map.put("total_system_memory", "系统总内存");map.put("total_system_memory_human", "以人类可读的方式返回系统总内存");map.put("used_memory_lua_human", "以人类可读的方式返回Lua 引擎所使用的内存大小");map.put("maxmemory", "最大内存限制,0表示无限制");map.put("maxmemory_human", "以人类可读的方式返回最大限制内存");map.put("maxmemory_policy", "超过内存限制后的处理策略");map.put("loading", "服务器是否正在载入持久化文件");map.put("rdb_changes_since_last_save", "离最近一次成功生成rdb文件,写入命令的个数,即有多少个写入命令没有持久化");map.put("rdb_bgsave_in_progress", "服务器是否正在创建rdb文件");map.put("rdb_last_save_time", "离最近一次成功创建rdb文件的时间戳。当前时间戳 - rdb_last_save_time=多少秒未成功生成rdb文件");map.put("rdb_last_bgsave_status", "最近一次rdb持久化是否成功");map.put("rdb_last_bgsave_time_sec", "最近一次成功生成rdb文件耗时秒数");map.put("rdb_current_bgsave_time_sec", "如果服务器正在创建rdb文件,那么这个域记录的就是当前的创建操作已经耗费的秒数");map.put("aof_enabled", "是否开启了aof");map.put("aof_rewrite_in_progress", "标识aof的rewrite操作是否在进行中");map.put("aof_rewrite_scheduled","rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite ");map.put("aof_last_rewrite_time_sec", "最近一次aof rewrite耗费的时长");map.put("aof_current_rewrite_time_sec", "如果rewrite操作正在进行,则记录所使用的时间,单位秒");map.put("aof_last_bgrewrite_status", "上次bgrewrite aof操作的状态");map.put("aof_last_write_status", "上次aof写入状态");map.put("total_commands_processed", "redis处理的命令数");map.put("total_connections_received", "新创建连接个数,如果新创建连接过多,过度地创建和销毁连接对性能有影响,说明短连接严重或连接池使用有问题,需调研代码的连接设置");map.put("instantaneous_ops_per_sec", "redis当前的qps,redis内部较实时的每秒执行的命令数");map.put("total_net_input_bytes", "redis网络入口流量字节数");map.put("total_net_output_bytes", "redis网络出口流量字节数");map.put("instantaneous_input_kbps", "redis网络入口kps");map.put("instantaneous_output_kbps", "redis网络出口kps");map.put("rejected_connections", "拒绝的连接个数,redis连接个数达到maxclients限制,拒绝新连接的个数");map.put("sync_full", "主从完全同步成功次数");map.put("sync_partial_ok", "主从部分同步成功次数");map.put("sync_partial_err", "主从部分同步失败次数");map.put("expired_keys", "运行以来过期的key的数量");map.put("evicted_keys", "运行以来剔除(超过了maxmemory后)的key的数量");map.put("keyspace_hits", "命中次数");map.put("keyspace_misses", "没命中次数");map.put("pubsub_channels", "当前使用中的频道数量");map.put("pubsub_patterns", "当前使用的模式的数量");map.put("latest_fork_usec", "最近一次fork操作阻塞redis进程的耗时数,单位微秒");map.put("role", "实例的角色,是master or slave");map.put("connected_slaves", "连接的slave实例个数");map.put("master_repl_offset", "主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟");map.put("repl_backlog_active", "复制积压缓冲区是否开启");map.put("repl_backlog_size", "复制积压缓冲大小");map.put("repl_backlog_first_byte_offset", "复制缓冲区里偏移量的大小");map.put("repl_backlog_histlen","此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小");map.put("used_cpu_sys", "将所有redis主进程在核心态所占用的CPU时求和累计起来");map.put("used_cpu_user", "将所有redis主进程在用户态所占用的CPU时求和累计起来");map.put("used_cpu_sys_children", "将后台进程在核心态所占用的CPU时求和累计起来");map.put("used_cpu_user_children", "将后台进程在用户态所占用的CPU时求和累计起来");map.put("cluster_enabled", "实例是否启用集群模式");map.put("db0", "db0的key的数量,以及带有生存期的key的数,平均存活时间");}private String key;private String value;private String description;public String getKey() {return key;}public void setKey(String key) {this.key = key;this.description = map.get(this.key);}public String getValue() {return value;}public void setValue(String value) {this.value = value;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}@Overridepublic String toString() {return "RedisInfo{" +"key='" + key + '\'' +", value='" + value + '\'' +", description='" + description + '\'' +'}';}
}
通过redisTemplate的execute方法获取RedisConnection的连接信息
@Autowired
private RedisTemplate<String, Object> redisTemplate;private RedisConnection execute() {return (RedisConnection) redisTemplate.execute(new RedisCallback() {@Overridepublic Object doInRedis(RedisConnection redisConnection) throws DataAccessException{return redisConnection;}});
}
再把信息塞进我们的实体类中
@Override
public List<RedisInfo> getRedisInfo() {try {List<RedisInfo> list = new ArrayList<>();Properties info = execute().info();for (String key : info.stringPropertyNames()) {RedisInfo redisInfo = new RedisInfo();redisInfo.setKey(key);redisInfo.setValue(info.getProperty(key));list.add(redisInfo);}return list;} catch (Exception e) {e.printStackTrace();return new ArrayList<>();}
}
便能获取到redis各项性能的信息
拿到Redis的性能信息就可以根据实际性能进行一些避坑操作,因为咱们平台大多时候都是多组件共用同一个redis的,所以在使用redis过程中也要考虑到不能影响其他组件的正常运行。
相关文章:

获取平台Redis各项性能指标
业务场景 在XXXX项目中把A网的过车数据传到B网中,其中做了一个业务处理,就是如果因为网络或者其他原因导致把数据传到B网失败,就会把数据暂时先存到redis里,并且执行定时任务重新发送失败的。 问题 不过现场的情况比较不稳定。出…...

STM32 HAL 点灯
首先从点灯开始 完整函数如下: #include "led.h" #include "sys.h"//包含了stm32f1xx.h(包含各种寄存器定义、中断向量定义、常量定义等)//初始化GPIO口 void led_init(void) {GPIO_InitTypeDef gpio_initstruct;//打开…...
【http作业】
1.关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld #关闭防火墙 [rootlocalhost ~]# setenforce 0 2.下载nginx包 [rootlocalhost ~]# mount /dev/sr0 /mnt #挂载目录 [rootlocalhost ~]# yum install nginx -y #下载nginx包 3.增加多条端口 [rootlocalhost ~]# n…...

WPF+MVVM案例实战(十一)- 环形进度条实现
文章目录 1、运行效果2、功能实现1、文件创建与代码实现2、角度转换器实现3、命名空间引用3、源代码下载1、运行效果 2、功能实现 1、文件创建与代码实现 打开 Wpf_Examples 项目,在Views 文件夹下创建 CircularProgressBar.xaml 窗体文件。 CircularProgressBar.xaml 代码实…...
简述MCU微控制器
目录 一、MCU 的主要特点: 二、常见 MCU 系列: 三、应用场景: MCU 是微控制器(Microcontroller Unit)的缩写,指的是一种小型计算机,专门用于嵌入式系统。它通常集成了中央处理器(…...
微服务的雪崩问题
微服务的雪崩问题: 微服务调用链路中的某个服务故障,引起整个链路种的所有微服务都不可用。这就是微服务的雪崩问题。(级联失败),具体表现出来就是微服务之间相互调用,服务的提供者出现阻塞或者故障&#x…...

Java基础(4)——构建字符串(干货)
今天聊Java构建字符串以及其内存原理 我们先来看一个小例子。一个是String,一个是StringBuilder. 通过结果对比,StringBuilder要远远快于String. String/StringBuilder/StringBuffer这三个构建字符串有什么区别? 拼接速度上,StringBuilder…...

logback日志脱敏后异步写入文件
大家项目中肯定都会用到日志打印,目的是为了以后线上排查问题方便,但是有些企业对输出的日志包含的敏感(比如:用户身份证号,银行卡号,手机号等)信息要进行脱敏处理。 哎!我们最近就遇到了日志脱敏的改造。可…...

电容的基本知识
1.电容的相关公式 2.电容并联和串联的好处 电容并联的好处: 增加总电容值: 并联连接的电容器可以增加总的电容值,这对于需要较大电容值来滤除高频噪声或储存更多电荷的应用非常有用。 改善频率响应: 并联不同的电容值可以设计一个滤波器,以在特定的频率范围内提供更好的滤…...

【Axure高保真原型】分级树筛选中继器表格
今天和大家分享分级树筛选中继器表格的原型模板,点击树的箭头可以展开或者收起子级内容,点击内容,可以筛选出该内容及子级内容下所有的表格数据。左侧的树和右侧的表格都是用中继器制作的,所以使用也很方便,只需要在中…...
STM32 I2C通信:硬件I2C与软件模拟I2C的区别
文章目录 STM32 I2C通信:硬件I2C与软件模拟I2C的区别。一、硬件I2C速度快:实现简单:稳定性好: 二、软件模拟I2C灵活性高:支持多路通信: 三、选择哪种方式? STM32 I2C通信:硬件I2C与软…...

服务器新建用户
文章目录 前言一、步骤二、问题三、赋予管理员权限总结 前言 环境: 一、步骤 创建用户需要管理员权限sudo sudo useradd tang为用户设置密码 sudo passwd tang设置密码后,可以尝试使用 su 切换到 tang 用户,确保该用户可以正常使用&#…...

鸿蒙开发融云demo发送图片消息
鸿蒙开发融云demo发送图片消息 融云鸿蒙版是不带UI的,得自己一步步搭建。 这次讲如何发送图片消息,选择图片,显示图片消息。 还是有点难度的,好好看,好好学。 一、思路: 选择图片用:photoVie…...

音视频入门基础:AAC专题(11)——AudioSpecificConfig简介
音视频入门基础:AAC专题系列文章: 音视频入门基础:AAC专题(1)——AAC官方文档下载 音视频入门基础:AAC专题(2)——使用FFmpeg命令生成AAC裸流文件 音视频入门基础:AAC…...

OpenCV基本操作(python开发)——(8)实现芯片瑕疵检测
OpenCV基本操作(python开发)——(1) 读取图像、保存图像 OpenCV基本操作(python开发)——(2)图像色彩操作 OpenCV基本操作(python开发)——(3&…...

聚水潭商品信息集成到MySQL的高效解决方案
聚水潭商品信息集成到MySQL的技术案例分享 在数据驱动的业务环境中,如何高效地实现不同系统之间的数据对接和集成,是每个企业面临的重要挑战。本文将聚焦于一个具体的系统对接集成案例:将聚水潭平台上的商品信息单集成到BI斯莱蒙的MySQL数据…...

# centos6.5 使用 yum list 报错Error Cannot find a valid baseurl for repo bas 解决方法
centos6.5 使用 yum list 报错Error Cannot find a valid baseurl for repo bas 解决方法 一、问题描述: centos6.5 使用 yum list 报错Error Cannot find a valid baseurl for repo bas 如下图: 二、问题分析: 官方已停止对CentOS 6的更…...

【专题】2023-2024中国保险数字化营销调研报告汇总PDF洞察(附原数据表)
原文链接: https://tecdat.cn/?p38063 在时代浪潮的推动下,中国保险行业正经历着一场波澜壮阔的变革之旅。 2023 年,中国经济迈向高质量发展阶段,保险公司纷纷聚焦队伍转型,专业化、职业化代理人成为行业新方向。回…...

““ 引用类型应用举例
#include <iostream> //使能cin(),cout(); #include <stdlib.h> //使能exit(); #include <iomanip> //使能setbase(),setfill(),setw(),setprecision(),setiosflags()和resetiosflags(); //setbase( char x )是设置输出数字的基数,如输出进制数则用se…...
数字图像处理 - 基于ubuntu20.04运行.NET6+OpenCVSharp项目
一、简述 上一篇Ubuntu20.04 更新Nvidia驱动 + 安装CUDA12.1 + cudnn8.9.7-CSDN博客,记录了Ubuntu20.04 更新Nvidia驱动 + 安装CUDA12.1 + cudnn8.9.7的过程,最终的目的是要这些服务器上运行.net6的程序,进行图像处理、onnxruntime推理等。 这里记录进行OpenCVSharp的安装和…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...