# 🚀 文件下载缓存机制说明 ## 📋 功能概述 为了提高文件下载性能,减少对MinIO存储的重复请求,系统实现了基于内存的文件缓存机制。该机制具有以下特性: ### ✨ 核心特性 - **LRU淘汰策略**: 当缓存空间不足时,自动淘汰最久未访问的文件 - **智能大小控制**: 只缓存小于50MB的文件,避免内存溢出 - **过期时间管理**: 缓存条目具有30分钟的有效期 - **并发安全**: 使用读写锁保证多线程环境下的数据一致性 - **统计监控**: 提供缓存命中率、大小等统计信息 - **配置化管理**: 所有缓存参数可通过配置文件调整 ## 🔧 配置参数 ### 基础配置 在 `application.yml` 或 `application-dev.yml` 中添加以下配置: ```yaml system: file-cache: # 是否启用文件缓存 enabled: true # 最大缓存文件数量 max-cache-size: 100 # 最大缓存大小(字节)- 500MB max-cache-size-bytes: 524288000 # 缓存过期时间(毫秒)- 30分钟 expire-time-ms: 1800000 # 最大缓存单个文件大小(字节)- 50MB max-single-file-size: 52428800 # LRU淘汰比例(百分比) evict-ratio: 20 # 是否启用缓存统计 enable-stats: true # 缓存清理间隔(毫秒)- 5分钟 cleanup-interval-ms: 300000 ``` ### 参数说明 | 参数名 | 默认值 | 说明 | |--------|--------|------| | `enabled` | `true` | 是否启用文件缓存功能 | | `max-cache-size` | `100` | 缓存的最大文件数量 | | `max-cache-size-bytes` | `524288000` | 缓存的最大总大小(500MB) | | `expire-time-ms` | `1800000` | 缓存条目的过期时间(30分钟) | | `max-single-file-size` | `52428800` | 单个文件的最大缓存大小(50MB) | | `evict-ratio` | `20` | LRU淘汰时移除的条目比例(20%) | | `enable-stats` | `true` | 是否启用缓存统计功能 | | `cleanup-interval-ms` | `300000` | 自动清理过期条目的间隔(5分钟) | ## 🚀 使用方法 ### 1. 文件下载 缓存机制对用户透明,正常使用文件下载接口即可: ```http GET /resource/oss/download/{ossId} ``` 系统会自动: 1. 检查缓存中是否存在该文件 2. 如果存在且未过期,直接从缓存返回 3. 如果不存在或已过期,从MinIO下载并缓存 ### 2. 缓存管理API #### 获取缓存统计信息 ```http GET /resource/oss/cache/stats ``` 返回示例: ```json { "code": 200, "msg": "操作成功", "data": { "cacheSize": 25, "currentCacheSizeBytes": 104857600, "maxCacheSizeBytes": 524288000, "cacheHits": 150, "cacheMisses": 50, "hitRate": "75.00%" } } ``` #### 清空缓存 ```http DELETE /resource/oss/cache/clear ``` #### 移除指定文件缓存 ```http DELETE /resource/oss/cache/{ossId} ``` ## 📊 性能优化 ### 缓存命中率优化 - **增加缓存大小**: 对于内存充足的环境,适当增加 `max-cache-size-bytes` - **调整文件数量**: 对于小文件较多的场景,增加 `max-cache-size` - **优化过期时间**: 根据文件访问频率调整 `expire-time-ms` ### 内存使用优化 - **控制单个文件大小**: 根据实际情况调整 `max-single-file-size` - **调整淘汰策略**: 通过 `evict-ratio` 控制淘汰比例 - **定期清理**: 设置合适的 `cleanup-interval-ms` ### 监控指标 - **缓存命中率**: 目标 > 70% - **内存使用率**: 监控缓存占用的内存大小 - **响应时间**: 缓存命中时的下载速度应显著提升 ## 🔍 技术实现 ### 核心组件 #### 1. 缓存条目类 (CacheEntry) ```java private class CacheEntry { private final byte[] data; // 文件数据 private final long size; // 文件大小 private final long createTime; // 创建时间 private final long lastAccessTime; // 最后访问时间 private final String contentType; // 内容类型 } ``` #### 2. LRU淘汰策略 ```java private void evictLRUEntries() { // 按最后访问时间排序 List> entries = new ArrayList<>(fileCache.entrySet()); entries.sort((e1, e2) -> Long.compare(e1.getValue().getLastAccessTime(), e2.getValue().getLastAccessTime())); // 淘汰最旧的20%条目 int evictCount = Math.max(1, entries.size() / 5); for (int i = 0; i < evictCount && i < entries.size(); i++) { Map.Entry entry = entries.get(i); fileCache.remove(entry.getKey()); currentCacheSize.addAndGet(-entry.getValue().getSize()); } } ``` #### 3. 并发安全 - 使用 `ConcurrentHashMap` 存储缓存数据 - 使用 `ReentrantReadWriteLock` 保证读写安全 - 使用 `AtomicLong` 统计缓存大小和命中率 ### 工作流程 1. **文件下载请求** ``` 用户请求 → 权限验证 → 检查缓存 → 返回文件 ``` 2. **缓存命中流程** ``` 检查缓存 → 验证过期 → 直接返回 → 更新统计 ``` 3. **缓存未命中流程** ``` 检查缓存 → 从MinIO下载 → 添加到缓存 → 返回文件 ``` 4. **缓存管理流程** ``` 检查大小限制 → LRU淘汰 → 清理过期 → 添加新条目 ``` ## ⚠️ 注意事项 ### 1. 内存管理 - 缓存会占用JVM堆内存,需要合理配置缓存大小 - 建议监控应用的内存使用情况 - 大文件不会被缓存,避免内存溢出 ### 2. 数据一致性 - 缓存的文件数据可能与MinIO中的文件不同步 - 如果需要最新数据,可以手动清除缓存 - 建议在文件更新后清除相关缓存 ### 3. 性能考虑 - 缓存命中时响应速度显著提升 - 缓存未命中时会有轻微的性能开销(用于缓存数据) - 建议根据实际访问模式优化缓存参数 ### 4. 安全考虑 - 缓存数据存储在内存中,应用重启后会丢失 - 敏感文件建议设置较短的过期时间 - 可以通过API手动管理缓存 ## 🔧 故障排查 ### 常见问题 1. **缓存命中率低** - 检查缓存大小配置是否合理 - 分析文件访问模式 - 调整过期时间 2. **内存使用过高** - 减少缓存大小限制 - 降低单个文件大小限制 - 增加淘汰比例 3. **缓存不生效** - 检查 `enabled` 配置是否为 `true` - 确认文件大小是否超过限制 - 查看日志中的缓存相关信息 ### 监控建议 1. **定期检查缓存统计** ```bash curl -X GET "http://localhost:8080/resource/oss/cache/stats" ``` 2. **监控应用内存使用** ```bash jstat -gc 1000 ``` 3. **查看缓存相关日志** ```bash tail -f logs/application.log | grep "cache" ``` ## 📈 性能测试 ### 测试场景 1. **首次下载**: 从MinIO下载并缓存 2. **缓存命中**: 从内存直接返回 3. **并发下载**: 多用户同时下载同一文件 4. **大文件下载**: 超过缓存大小限制的文件 ### 预期性能提升 - **缓存命中时**: 响应时间减少 80-90% - **并发访问**: 显著减少MinIO压力 - **整体性能**: 平均下载速度提升 60-80% --- **📝 维护说明**: 本文档基于文件缓存机制的实现,如需修改缓存策略或参数,请同步更新相关代码和配置。