18.7.6 Redis内存优化与过期策略
1. Redis内存使用分析
1.1 内存使用结构
public class RedisMemoryAnalysis {
/*
* Redis内存使用分析:
*
* 1. 内存组成
* - 数据内存:存储键值对数据
* - 过期字典:存储键的过期时间
* - 输出缓冲区:客户端输出缓冲
* - 查询缓冲区:客户端查询缓冲
* - 复制积压缓冲区:主从复制缓冲
*
* 2. 内存统计
* - used_memory:Redis分配的内存总量
* - used_memory_rss:操作系统分配的内存
* - used_memory_peak:内存使用峰值
* - mem_fragmentation_ratio:内存碎片率
*
* 3. 优化目标
* - 减少内存使用
* - 降低内存碎片
* - 提高内存利用率
*/
public void demonstrateMemoryAnalysis() {
System.out.println("=== Redis内存使用分析演示 ===");
MockRedisMemoryAnalyzer analyzer = new MockRedisMemoryAnalyzer();
demonstrateMemoryInfo(analyzer);
demonstrateMemoryUsageByType(analyzer);
demonstrateFragmentationAnalysis(analyzer);
}
private void demonstrateMemoryInfo(MockRedisMemoryAnalyzer analyzer) {
System.out.println("--- 内存信息统计 ---");
RedisMemoryInfo memInfo = analyzer.getMemoryInfo();
System.out.println("1. 基础内存信息:");
System.out.println(" used_memory: " + formatBytes(memInfo.getUsedMemory()));
System.out.println(" used_memory_rss: " + formatBytes(memInfo.getUsedMemoryRss()));
System.out.println(" used_memory_peak: " + formatBytes(memInfo.getUsedMemoryPeak()));
System.out.println(" mem_fragmentation_ratio: " + memInfo.getFragmentationRatio());
System.out.println("\n2. 内存使用评估:");
if (memInfo.getFragmentationRatio() > 1.5) {
System.out.println(" ⚠️ 内存碎片率较高,建议进行碎片整理");
} else {
System.out.println(" ✅ 内存碎片率正常");
}
double memoryUsagePercent = (double) memInfo.getUsedMemory() / memInfo.getMaxMemory() * 100;
if (memoryUsagePercent > 80) {
System.out.println(" ⚠️ 内存使用率过高: " + String.format("%.1f%%", memoryUsagePercent));
} else {
System.out.println(" ✅ 内存使用率正常: " + String.format("%.1f%%", memoryUsagePercent));
}
}
private void demonstrateMemoryUsageByType(MockRedisMemoryAnalyzer analyzer) {
System.out.println("\n--- 数据类型内存使用 ---");
java.util.Map<String, Long> memoryByType = analyzer.getMemoryUsageByType();
System.out.println("1. 各数据类型内存占用:");
long totalMemory = memoryByType.values().stream().mapToLong(Long::longValue).sum();
for (java.util.Map.Entry<String, Long> entry : memoryByType.entrySet()) {
double percentage = (double) entry.getValue() / totalMemory * 100;
System.out.println(String.format(" %s: %s (%.1f%%)",
entry.getKey(), formatBytes(entry.getValue()), percentage));
}
System.out.println("\n2. 优化建议:");
String maxType = memoryByType.entrySet().stream()
.max(java.util.Map.Entry.comparingByValue())
.map(java.util.Map.Entry::getKey)
.orElse("unknown");
System.out.println(" 主要内存消耗类型: " + maxType);
System.out.println(" 建议针对 " + maxType + " 类型进行优化");
}
private void demonstrateFragmentationAnalysis(MockRedisMemoryAnalyzer analyzer) {
System.out.println("\n--- 内存碎片分析 ---");
FragmentationInfo fragInfo = analyzer.getFragmentationInfo();
System.out.println("1. 碎片详细信息:");
System.out.println(" 分配器: " + fragInfo.getAllocator());
System.out.println(" 活跃碎片: " + formatBytes(fragInfo.getActiveDefrag()));
System.out.println(" 懒惰释放: " + formatBytes(fragInfo.getLazyFree()));
System.out.println("\n2. 碎片整理建议:");
if (fragInfo.shouldDefrag()) {
System.out.println(" 建议执行: MEMORY PURGE");
System.out.println(" 或配置自动碎片整理");
} else {
System.out.println(" 当前碎片率可接受,无需整理");
}
}
private String formatBytes(long bytes) {
if (bytes < 1024) return bytes + "B";
if (bytes < 1024 * 1024) return String.format("%.1fKB", bytes / 1024.0);
if (bytes < 1024 * 1024 * 1024) return String.format("%.1fMB", bytes / (1024.0 * 1024));
return String.format("%.1fGB", bytes / (1024.0 * 1024 * 1024));
}
}
// 模拟Redis内存分析器
class MockRedisMemoryAnalyzer {
public RedisMemoryInfo getMemoryInfo() {
return new RedisMemoryInfo(
104857600L, // 100MB used_memory
125829120L, // 120MB used_memory_rss
157286400L, // 150MB used_memory_peak
1073741824L, // 1GB max_memory
1.2 // fragmentation_ratio
);
}
public java.util.Map<String, Long> getMemoryUsageByType() {
java.util.Map<String, Long> memoryByType = new java.util.LinkedHashMap<>();
memoryByType.put("String", 52428800L); // 50MB
memoryByType.put("Hash", 31457280L); // 30MB
memoryByType.put("List", 10485760L); // 10MB
memoryByType.put("Set", 5242880L); // 5MB
memoryByType.put("ZSet", 3145728L); // 3MB
memoryByType.put("Stream", 2097152L); // 2MB
return memoryByType;
}
public FragmentationInfo getFragmentationInfo() {
return new FragmentationInfo("jemalloc", 2097152L, 1048576L, true);
}
}
// Redis内存信息
class RedisMemoryInfo {
private long usedMemory;
private long usedMemoryRss;
private long usedMemoryPeak;
private long maxMemory;
private double fragmentationRatio;
public RedisMemoryInfo(long usedMemory, long usedMemoryRss, long usedMemoryPeak,
long maxMemory, double fragmentationRatio) {
this.usedMemory = usedMemory;
this.usedMemoryRss = usedMemoryRss;
this.usedMemoryPeak = usedMemoryPeak;
this.maxMemory = maxMemory;
this.fragmentationRatio = fragmentationRatio;
}
public long getUsedMemory() { return usedMemory; }
public long getUsedMemoryRss() { return usedMemoryRss; }
public long getUsedMemoryPeak() { return usedMemoryPeak; }
public long getMaxMemory() { return maxMemory; }
public double getFragmentationRatio() { return fragmentationRatio; }
}
// 碎片信息
class FragmentationInfo {
private String allocator;
private long activeDefrag;
private long lazyFree;
private boolean shouldDefrag;
public FragmentationInfo(String allocator, long activeDefrag, long lazyFree, boolean shouldDefrag) {
this.allocator = allocator;
this.activeDefrag = activeDefrag;
this.lazyFree = lazyFree;
this.shouldDefrag = shouldDefrag;
}
public String getAllocator() { return allocator; }
public long getActiveDefrag() { return activeDefrag; }
public long getLazyFree() { return lazyFree; }
public boolean shouldDefrag() { return shouldDefrag; }
}
2. 数据结构优化
2.1 编码优化策略
public class RedisDataStructureOptimization {
/*
* Redis数据结构编码优化:
*
* 1. String优化
* - 整数编码:小整数使用int编码
* - 短字符串:使用embstr编码
* - 长字符串:使用raw编码
*
* 2. Hash优化
* - ziplist:字段少且值小时使用
* - hashtable:字段多或值大时使用
*
* 3. List优化
* - quicklist:结合ziplist和linkedlist
* - 压缩配置:list-compress-depth
*
* 4. Set优化
* - intset:整数集合,内存效率高
* - hashtable:通用哈希表
*
* 5. ZSet优化
* - ziplist:元素少时使用
* - skiplist:元素多时使用
*/
public void demonstrateDataStructureOptimization() {
System.out.println("=== Redis数据结构优化演示 ===");
demonstrateStringOptimization();
demonstrateHashOptimization();
demonstrateListOptimization();
demonstrateSetOptimization();
demonstrateZSetOptimization();
}
private void demonstrateStringOptim
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经

