获取平台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的安装和…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
