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圣经

全部评论

相关推荐

10-29 19:42
门头沟学院 Java
点赞 评论 收藏
分享
牛客nb666号:见天才的门槛罢了查看图片
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务