Redis 实时监控与性能分析:Jedis + INFO 命令实战
本文介绍了基于Redis INFO命令和Jedis客户端实现Redis实时监控的方法。通过Java代码调用Redis INFO指令,可以获取内存使用、QPS、连接数、慢日志等核心指标数据。文章详细说明了技术架构,包括JedisPool连接池配置、监控数据采集层的实现,以及如何获取Redis服务器完整INFO信息和慢日志。配置部分展示了RedisConfig和application.yml的设置,为
·
Redis 实时监控与性能分析:Jedis + INFO 命令实战
基于 Redis INFO 命令和 Jedis 客户端,实现 Redis 运行状态的实时监控,包括内存使用、QPS、连接数、慢日志、缓存命中率等核心指标,并附带完整的 INFO 参数中文翻译对照表。
一、项目概述
1.1 监控目标
通过 Java 代码调用 Redis INFO 指令,获取 Redis 实例的运行数据,实现以下监控维度:
| 监控维度 | 关键指标 |
|---|---|
| 内存使用 | used_memory、used_memory_rss、mem_fragmentation_ratio |
| 性能指标 | instantaneous_ops_per_sec(QPS)、命中率 |
| 连接状态 | connected_clients、blocked_clients、rejected_connections |
| 持久化 | rdb_last_save_time、aof_enabled、aof_current_size |
| 复制状态 | master_repl_offset、connected_slaves、sync 状态 |
| 键统计 | keyspace_hits、keyspace_misses、expired_keys、evicted_keys |
| 慢日志 | slowlog 查询与重置 |
1.2 技术架构
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐
│ INFO 命令 │◄────│ JedisPool │◄────│ RedisConfig │
│ (Redis Server) │ │ (连接池) │ │ (Spring Boot) │
└─────────────────┘ └──────┬───────┘ └─────────────────┘
│
┌──────────▼──────────┐
│ JedisUtil │
│ (监控数据采集层) │
└──────────┬──────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
RedisMonitoringInfo RedisIdService RedisMonitoringService
(概览面板数据) (全量指标接口) (动态图表数据)
│ │ │
└────────────────────┼────────────────────┘
▼
Redis实时监控页面
(内存/QPS/CPU/命中率)
二、基础配置
2.1 RedisConfig:JedisPool 配置
package com.redis.monitor.config;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.logging.Logger;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Bean
public JedisPool redisPoolFactory() {
Logger.getLogger(getClass()).info("JedisPool注入成功!!");
Logger.getLogger(getClass()).info("redis地址:" + host + ":" + port);
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 可按需配置连接池参数
jedisPoolConfig.setMaxTotal(200);
jedisPoolConfig.setMaxIdle(50);
jedisPoolConfig.setMinIdle(10);
jedisPoolConfig.setTestOnBorrow(true);
jedisPoolConfig.setTestOnReturn(true);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
return jedisPool;
}
}
2.2 application.yml 配置
spring:
redis:
host: 127.0.0.1
port: 6379
password: yourpassword
timeout: 5000
三、监控数据采集层
3.1 JedisUtil:核心采集工具
package com.redis.monitor.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Client;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.util.Slowlog;
import java.util.List;
@Component
public class JedisUtil {
@Autowired
JedisPool jedisPool;
/**
* 获取 Redis 服务器完整 INFO 信息
*/
public String getRedisInfo() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
Client client = jedis.getClient();
client.info();
String info = client.getBulkReply();
return info;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 返还到连接池
jedis.close();
}
return null;
}
/**
* 获取慢日志列表
* @param entries 返回的条目数
*/
public List<Slowlog> getLogs(long entries) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
List<Slowlog> logList = jedis.slowlogGet(entries);
return logList;
} finally {
jedis.close();
}
}
/**
* 获取慢日志总条数
*/
public Long getLogsLen() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
long logLen = jedis.slowlogLen();
return logLen;
} finally {
jedis.close();
}
}
/**
* 清空慢日志
*/
public String logEmpty() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
return jedis.slowlogReset();
} finally {
jedis.close();
}
}
/**
* 获取当前数据库 Key 的数量
*/
public Long dbSize() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
Client client = jedis.getClient();
client.dbSize();
return client.getIntegerReply();
} finally {
jedis.close();
}
}
}
四、INFO 参数中文翻译对照
4.1 RedisInfoDetail:参数翻译器
package com.redis.monitor.model;
import java.util.HashMap;
import java.util.Map;
/**
* Redis INFO 命令返回参数的中文翻译解释
* 将 Redis 的英文参数名映射为可读的中文描述
*/
public class RedisInfoDetail {
private static Map<String, String> map = new HashMap<String, String>();
static {
// ========== Server 部分 ==========
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("redis_build_id", "Redis 构建ID");
map.put("redis_mode", "Redis启动模式:standalone、Sentinel、Cluster");
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("hz", "redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率");
map.put("configured_hz", "redis的配置状态频率");
map.put("executable", "服务器可执行文件的路径");
map.put("config_file", "启动 redis 配置文件");
map.put("lru_clock", "以分钟为单位进行自增的时钟,用于 LRU 管理");
// ========== Clients 部分 ==========
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("client_recent_max_output_buffer", "当前连接的客户端当中,最长的输出列表");
map.put("client_recent_max_input_buffer", "当前连接的客户端当中,最大输入缓存");
// ========== Memory 部分 ==========
map.put("used_memory", "由 Redis 分配器分配的内存总量,以字节(byte)为单位");
map.put("used_memory_human", "以人类可读的格式返回 Redis 分配的内存总量");
map.put("used_memory_rss", "从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致");
map.put("used_memory_rss_human", "以可读的格式,操作系统角度,返回 redis 分配的内存总量");
map.put("used_memory_peak", "Redis 的内存消耗峰值(以字节为单位)");
map.put("used_memory_peak_human", "以人类可读的格式返回 Redis 的内存消耗峰值");
map.put("total_system_memory", "主机拥有的内存总量");
map.put("total_system_memory_human", "以可读的格式返回主机拥有的内存总量");
map.put("used_memory_lua", "Lua 引擎所使用的内存大小(以字节为单位)");
map.put("used_memory_lua_human", "以可读的格式返回Lua引擎使用内存");
map.put("maxmemory_human", "以可读的格式返回Redis实例的最大内存配置");
map.put("maxmemory", "Redis实例的最大内存配置");
map.put("maxmemory_policy", "当达到maxmemory时的淘汰策略");
map.put("used_memory_startup", "启动时消耗的初始内存量(以字节为单位)");
map.put("used_memory_overhead", "数据集的大小(以字节为单位,used_memory - used_memory_overhead)");
map.put("used_memory_peak_perc", "used_memory_peak在used_memory中所占的百分比");
map.put("used_memory_dataset", "数据集的大小(以字节为单位,used_memory - used_memory_overhead)");
map.put("used_memory_dataset_perc", "used_memory_dataset在净内存(used_memory-used_memory_startup)使用量中所占的百分比");
map.put("mem_aof_buffer", "aof时,占用的缓冲");
map.put("mem_allocator", "内存分配器(在编译时选择)");
map.put("mem_clients_normal", "Redis的客户端主的分配信息量");
map.put("mem_clients_slaves", "Redis的客户端从的分配信息量");
map.put("mem_replication_backlog", "Redis的内存复制积压分配信息量");
map.put("mem_not_counted_for_evict", "被驱逐的大小");
map.put("mem_fragmentation_bytes", "内存碎片的大小(以字节为单位)");
map.put("mem_fragmentation_ratio", "内存碎片率,used_memory_rss 和 used_memory 之间的比率");
map.put("rss_overhead_ratio", "常驻内存开销比例");
map.put("rss_overhead_bytes", "常驻内存开销大小(以字节为单位)");
map.put("allocator_rss_bytes", "分配器的常驻内存大小(以字节为单位)");
map.put("allocator_rss_ratio", "分配器常驻内存比例");
map.put("allocator_frag_bytes", "分配器的碎片大小(以字节为单位)");
map.put("allocator_frag_ratio", "分配器的碎片率");
map.put("allocator_resident", "分配器常驻的内存");
map.put("allocator_active", "分配器活跃的内存");
map.put("allocator_allocated", "分配器分配的内存");
map.put("used_memory_scripts_human", "人类使用过的记忆脚本");
map.put("used_memory_scripts", "Redis使用的内存脚本");
// ========== Persistence 部分 ==========
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文件的时间戳");
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("rdb_last_cow_size", "上一次RBD保存操作期间写时复制的大小(以字节为单位)");
map.put("aof_enabled", "aof是否开启");
map.put("aof_rewrite_in_progress", "aof的rewrite操作是否在进行中");
map.put("aof_last_cow_size", "上一次AOF保存操作期间写时复制的大小(以字节为单位)");
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", "若当前正在执行aof rewrite,指当前的已经耗费的时间");
map.put("aof_last_bgrewrite_status", "最近一次aof bgrewrite的状态");
map.put("aof_last_write_status", "最近一次aof写入状态");
map.put("aof_current_size", "aof文件当前大小");
map.put("aof_pending_rewrite", "rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite");
map.put("aof_buffer_length", "aof 缓冲区的大小");
map.put("aof_rewrite_buffer_length", "aof 重写缓冲区的大小");
map.put("aof_pending_bio_fsync", "后台IO队列中,等待fsync任务的个数");
map.put("aof_delayed_fsync", "被延迟的 fsync 调用数量");
// ========== Stats 部分 ==========
map.put("total_connections_received", "自启动起连接过的总数。如果连接过多,说明短连接严重或连接池使用有问题,需调研代码的连接设置");
map.put("total_commands_processed", "自启动起运行命令的总数");
map.put("instantaneous_ops_per_sec", "每秒执行的命令数,相当于QPS");
map.put("total_net_input_bytes", "网络入口流量字节数");
map.put("total_net_output_bytes", "网络出口流量字节数");
map.put("instantaneous_input_kbps", "网络入口kps");
map.put("instantaneous_output_kbps", "网络出口kps");
map.put("rejected_connections", "拒绝的连接个数,由于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("expired_stale_perc", "过期的比率");
map.put("expired_time_cap_reached_count", "过期计数");
map.put("keyspace_hits", "在main dictionary字典中成功查到的key个数");
map.put("keyspace_misses", "同上,未命中的key的个数");
map.put("pubsub_channels", "发布/订阅频道数");
map.put("pubsub_patterns", "发布/订阅模式数");
map.put("latest_fork_usec", "上次的fork操作使用的时间(单位ms)");
map.put("migrate_cached_sockets", "是否已经缓存了到该地址的连接");
map.put("slave_expires_tracked_keys", "从实例到期key数量");
// ========== Replication 部分 ==========
map.put("role", "当前实例的角色master还是slave");
map.put("connected_slaves", "slave的数量");
map.put("master_replid", "主实例启动随机字符串");
map.put("master_replid2", "主实例启动随机字符串2");
map.put("slave0", "slave机器的信息、状态");
map.put("master_repl_offset", "主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟,与master_replid可被用来标识主实例复制流中的位置。");
map.put("second_repl_offset", "主从同步偏移量2,此值如果和上面的offset相同说明主从一致没延迟");
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("repl_backlog_active", "复制缓冲区是否开启");
// ========== CPU 部分 ==========
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使用率");
// ========== Cluster 部分 ==========
map.put("cluster_enabled", "例是否启用集群模式");
// ========== Keyspace 部分 ==========
map.put("Keyspace", "redis的Keyspace_db0值");
// ========== 其他 ==========
map.put("active_defrag_running", "碎片整理是否处于活动状态");
map.put("active_defrag_hits", "主动碎片整理命中次数");
map.put("active_defrag_misses", "主动碎片整理未命中次数");
map.put("active_defrag_key_hits", "主动碎片整理key命中次数");
map.put("active_defrag_key_misses", "主动碎片整理key未命中次数");
map.put("lazyfree_pending_objects", "等待释放的对象数(由于使用ASYNC选项调用UNLINK或FLUSHDB和FLUSHALL)");
map.put("number_of_cached_scripts", "Redis缓存脚本的数量");
map.put("atomicvar_api", "Atomicvar API");
}
private String key;
private String value;
private String desctiption;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
this.desctiption = map.get(this.key);
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDesctiption() {
return desctiption;
}
public void setDesctiption(String desctiption) {
this.desctiption = desctiption;
}
@Override
public String toString() {
return "RedisInfoDetail [key=" + key + ", value=" + value
+ ", desctiption=" + desctiption + "]";
}
}
五、慢日志模型
5.1 Operate:慢查询日志实体
package com.redis.monitor.model;
/**
* Redis 慢查询日志实体
* 对应 SLOWLOG GET 返回的每条记录
*/
public class Operate {
private long id; // slowlog唯一编号id
private String executeTime; // 查询的时间戳
private String usedTime; // 查询的耗时(微妙),如表示本条命令查询耗时47微秒
private String args; // 查询命令,完整命令为 SLOWLOG GET,slowlog最多保存前面的31个key和128字符
public Operate() {}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getExecuteTime() {
return executeTime;
}
public void setExecuteTime(String executeTime) {
this.executeTime = executeTime;
}
public String getUsedTime() {
return usedTime;
}
public void setUsedTime(String usedTime) {
this.usedTime = usedTime;
}
public String getArgs() {
return args;
}
public void setArgs(String args) {
this.args = args;
}
}
六、监控服务接口
6.1 RedisMonitoringInfo:监控概览面板
package com.redis.monitor.service;
import java.util.Map;
/**
* 监控概览面板 - 获取 Redis 核心运行状态摘要
*/
public interface RedisMonitoringInfo {
/**
* @return 监控页面数据(进程ID、命中率、连接数、Key数、内存使用)
*/
Map<String, Object> getMonitoringInfo();
}
6.2 RedisMonitoring:动态图表数据
package com.redis.monitor.service;
import java.util.Map;
/**
* 监控动态图表 - 获取 Redis 实时动态数据
*/
public interface RedisMonitoring {
/**
* @param qps 采样QPS值
* @param time 时间差值(秒)
* @return 包含内存、CPU、QPS、时间戳的动态数据
*/
Map<String, Object> getMonitoring(Integer qps, Integer time);
}
6.3 RedisIdService:全量指标查询接口
package com.redis.monitor.service;
import com.redis.monitor.model.Operate;
import java.util.List;
import java.util.Map;
/**
* Redis 全量监控指标查询服务
*/
public interface RedisIdService {
/** 获取 Redis INFO 完整参数列表 */
List<Map<String, Object>> getRedisInfo();
/** 获取 QPS 动态数据 */
Double getDbSizeQps(Integer qps, Integer time);
/** 获取 Redis 慢日志列表 */
List<Operate> getLogs(long entries);
/** 获取日志总数 */
Long getLogLen();
/** 清空日志 */
String logEmpty();
/** 获取当前数据库中 key 的数量 */
Map<String, Object> getKeysSize();
/** 获取当前 Redis 使用内存大小情况 */
Map<String, Object> getMemeryInfo();
/** 获取内存详情列表 */
Map<String, Object> getMemeryInfolist();
/** 获取 Redis 内存大小 */
String getUsedMemory();
/** 获取内存碎片率 */
String getMemFragmentationRatio();
/** 获取 CPU 系统使用率 */
String getUsedCpuSys();
/** 获取 CPU 用户态使用率 */
String getUsedCpuUserChildren();
/** 获取总连接数 */
String getTotalConnectionsReceived();
/** 获取内存常驻集大小(RSS) */
String getUsedMemoryRss();
/** 获取当前客户端连接数 */
String getConnectedClients();
/** 获取缓存命中率 */
String getHitProbability();
/** 获取进程 ID */
String getProcessId();
/** 获取 Redis db 库总量 */
Integer getDbId();
/** 获取 Keyspace 信息 */
String getKeyspace();
/** 获取 key 值列表(分页) */
List<Map<String, Object>> getAllRedisVal2(Integer pageSize, Integer pageNumber, Integer id, String key);
/** 切换 Redis db 库 */
List<Map<String, Object>> getSwitchoverRedis();
}
七、监控服务实现
7.1 RedisMonitoringInfoServiceImpl:监控面板实现
package com.redis.monitor.service.impl;
import com.redis.monitor.service.RedisIdService;
import com.redis.monitor.service.RedisMonitoringInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* 监控概览面板实现
*/
@Service
public class RedisMonitoringInfoServiceImpl implements RedisMonitoringInfo {
@Autowired
private RedisIdService redisService;
@Override
public Map getMonitoringInfo() {
Map<String, Object> map = new HashMap<>();
Integer dbId = redisService.getDbId();
String processId = redisService.getProcessId();
String usedMemory = redisService.getUsedMemory();
String connectedClients = redisService.getConnectedClients();
String hitProbability = redisService.getHitProbability();
map.put("processId", processId);
map.put("hitProbability", hitProbability);
map.put("connectedClients", connectedClients);
map.put("keysSize", dbId);
map.put("usedMemory", usedMemory + "M");
return map;
}
}
7.2 RedisMonitoringServiceImpl:动态图表实现
package com.redis.monitor.service.impl;
import com.redis.monitor.service.RedisIdService;
import com.redis.monitor.service.RedisMonitoring;
import com.redis.monitor.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 动态图表数据实现
* 实时采集 Redis 内存、CPU、QPS 数据,供前端图表展示
*/
@Service
public class RedisMonitoringServiceImpl implements RedisMonitoring {
@Autowired
private RedisIdService redisService;
@Autowired
private RedisUtil redisUtils;
@Override
public Map<String, Object> getMonitoring(Integer qps, Integer time) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Map<String, Object> item = new HashMap<String, Object>();
List<Map<String, Object>> arrayList = new ArrayList<Map<String, Object>>();
// 采集当前时刻的监控数据
String usedMemory = redisService.getUsedMemory();
String usedCpuSys = redisService.getUsedCpuSys();
String usedMemoryRss = redisService.getUsedMemoryRss();
Double dbSizeQps = redisService.getDbSizeQps(qps, time);
// 组装内存数据
Map<String, Object> memeryInfomap = new HashMap<String, Object>();
memeryInfomap.put("usedMemoryRss", usedMemoryRss);
memeryInfomap.put("usedMemory", usedMemory + "M");
// 组装返回数据
item.put("dbSizeQps", dbSizeQps);
item.put("memeryInfomap", memeryInfomap);
item.put("usedCpuSys", usedCpuSys);
Date d = new Date();
String str = sdf.format(d);
item.put("date", str);
return item;
}
}
八、监控指标详解
8.1 核心监控指标说明
| 前端展示项 | 对应 INFO 参数 | 说明 |
|---|---|---|
| 进程ID | process_id | Redis 服务器进程 ID,用于进程级别监控 |
| 内存使用 | used_memory | 已分配内存总量(含碎片),单位 M |
| 内存常驻集 | used_memory_rss | 操作系统角度已分配内存,反映实际物理占用 |
| 内存碎片率 | mem_fragmentation_ratio | RSS/used_memory,>1.5 需要关注 |
| QPS | instantaneous_ops_per_sec | 每秒执行的命令数,核心性能指标 |
| 客户端连接数 | connected_clients | 当前连接数,异常升高需排查 |
| 缓存命中率 | hit/miss 比例 | keyspace_hits/(keyspace_hits+keyspace_misses) |
| CPU 使用率 | used_cpu_sys/user | 系统态/用户态 CPU 消耗 |
| 过期 Key | expired_keys | 自启动起过期 key 总数 |
| 淘汰 Key | evicted_keys | 内存不足被淘汰的 key 总数 |
| 慢查询 | slowlog | 超过 slowlog-log-slower-than 的查询 |
8.2 内存碎片率参考
| mem_fragmentation_ratio | 状态 | 建议 |
|---|---|---|
| ≈ 1.0 ~ 1.2 | 健康 | 正常范围 |
| 1.2 ~ 1.5 | 轻度碎片 | 可观察,必要时重启 |
| > 1.5 | 严重碎片 | 建议重启或使用 CONFIG SET activedefrag yes |
| < 1.0 | 异常 | 可能启用了交换分区,需检查内存 |
九、调用示例
9.1 Spring Boot 入口
package com.redis.monitor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisMonitorApplication {
public static void main(String[] args) {
SpringApplication.run(RedisMonitorApplication.class, args);
}
}
9.2 REST 控制器示例
@RestController
@RequestMapping("/redis/monitor")
public class RedisMonitorController {
@Autowired
private RedisMonitoringInfo redisMonitoringInfo;
@Autowired
private RedisMonitoring redisMonitoring;
/** 监控面板概览 */
@GetMapping("/overview")
public Map<String, Object> overview() {
return redisMonitoringInfo.getMonitoringInfo();
}
/** 动态图表数据 */
@GetMapping("/dynamic")
public Map<String, Object> dynamic(@RequestParam Integer qps,
@RequestParam Integer time) {
return redisMonitoring.getMonitoring(qps, time);
}
}
9.3 测试代码
@Service
public class MonitorTestService {
@Autowired
private JedisUtil jedisUtil;
public void testJedisUtil() {
// 1. 获取完整 INFO
String info = jedisUtil.getRedisInfo();
System.out.println(info);
// 2. 获取最近 10 条慢日志
List<Slowlog> logs = jedisUtil.getLogs(10);
for (Slowlog log : logs) {
System.out.printf("ID: %d, 耗时: %d 微秒, 命令: %s%n",
log.getId(), log.getTime(), log.getArgs());
}
// 3. 获取 Key 数量
Long dbSize = jedisUtil.dbSize();
System.out.println("当前数据库 Key 数量: " + dbSize);
}
}
十、总结
本文从零搭建了一套完整的 Redis 实时监控系统,核心亮点:
- JedisPool 连接池 + Spring Boot 集成,生产可用
- INFO 参数完整中文翻译(120+ 参数),一目了然
- 慢日志查询 + 清空,帮助定位性能瓶颈
- 三层接口设计:概览面板、动态图表、全量指标查询
- 核心监控指标详解:内存碎片率、QPS、命中率等
适用场景:
- Redis 运维监控面板开发
- 自定义 Redis 监控告警系统
- 学习 Redis INFO 命令各参数含义
扩展建议:
- 集成 RedisReactive 实现响应式监控
- 对接 Prometheus + Grafana 可视化
- 增加告警阈值配置(内存超限、QPS 突降等)
- 使用 RedisTimeSeries 模块存储时序监控数据
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)