获取平台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的安装和…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...