Files
hzdyjs/docs/开发文档/文件下载缓存机制说明.md
2025-08-03 15:50:45 +08:00

257 lines
7.1 KiB
Markdown

# 🚀 文件下载缓存机制说明
## 📋 功能概述
为了提高文件下载性能,减少对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<Map.Entry<Long, CacheEntry>> 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<Long, CacheEntry> 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 <pid> 1000
```
3. **查看缓存相关日志**
```bash
tail -f logs/application.log | grep "cache"
```
## 📈 性能测试
### 测试场景
1. **首次下载**: 从MinIO下载并缓存
2. **缓存命中**: 从内存直接返回
3. **并发下载**: 多用户同时下载同一文件
4. **大文件下载**: 超过缓存大小限制的文件
### 预期性能提升
- **缓存命中时**: 响应时间减少 80-90%
- **并发访问**: 显著减少MinIO压力
- **整体性能**: 平均下载速度提升 60-80%
---
**📝 维护说明**: 本文档基于文件缓存机制的实现,如需修改缓存策略或参数,请同步更新相关代码和配置。