加入图片缓存,每次从文件系统中提取相关的图片,加载成bytes,后续使用时直接从缓存中提取。减少IO读取次数,提高发送性能
This commit is contained in:
141
plugins/xiuren_image/CACHE_README.md
Normal file
141
plugins/xiuren_image/CACHE_README.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# 秀人图片插件 - 缓存功能说明
|
||||
|
||||
## 概述
|
||||
|
||||
秀人图片插件现在支持内存缓存功能,可以显著提高图片发送的性能,减少磁盘I/O操作。
|
||||
|
||||
## 缓存机制
|
||||
|
||||
### 1. 缓存策略
|
||||
- **默认缓存大小**: 10张图片(可配置)
|
||||
- **缓存类型**: 内存缓存,存储图片的bytes数据
|
||||
- **缓存策略**: LRU(最近最少使用)策略
|
||||
- **并发处理**: 使用deque的原子操作,无需额外锁机制
|
||||
|
||||
### 2. 工作流程
|
||||
1. 用户请求图片时,优先从内存缓存中获取
|
||||
2. 如果缓存中有图片,直接返回bytes数据
|
||||
3. 当缓存中只剩1张图片时,异步触发缓存填充
|
||||
4. 如果缓存为空,立即同步填充缓存
|
||||
5. 支持回退机制:如果缓存失败,回退到原来的磁盘读取方式
|
||||
|
||||
### 3. 性能优化
|
||||
- **减少磁盘I/O**: 避免频繁的磁盘读取操作
|
||||
- **异步填充**: 缓存填充在后台线程进行,不阻塞主流程
|
||||
- **智能预加载**: 在缓存即将耗尽时提前填充
|
||||
- **内存管理**: 使用deque限制缓存大小,防止内存溢出
|
||||
- **无锁设计**: 避免线程锁导致的死锁问题
|
||||
|
||||
## 配置说明
|
||||
|
||||
在 `config.toml` 文件中可以配置缓存参数:
|
||||
|
||||
```toml
|
||||
[XiurenImage]
|
||||
enable = true
|
||||
image_folder = '/mnt/nfs_share'
|
||||
cache_size = 10 # 内存缓存大小,默认10张图片
|
||||
command = ["图来", "秀人", "美图", "随机图片"]
|
||||
```
|
||||
|
||||
### 配置参数
|
||||
- `cache_size`: 缓存大小,建议设置为5-15张图片
|
||||
- `image_folder`: 图片存储目录
|
||||
- `enable`: 是否启用插件
|
||||
- `command`: 触发命令列表
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 基本使用
|
||||
用户发送以下命令即可获取随机图片:
|
||||
- `图来`
|
||||
- `秀人`
|
||||
- `美图`
|
||||
- `随机图片`
|
||||
|
||||
### 2. 缓存状态监控
|
||||
插件会在日志中记录缓存状态:
|
||||
```
|
||||
从缓存获取图片成功,路径:/path/to/image.jpg,当前缓存数量:4
|
||||
```
|
||||
|
||||
### 3. 测试缓存功能
|
||||
运行测试脚本验证缓存功能:
|
||||
```bash
|
||||
cd plugins/xiuren_image
|
||||
python test_cache.py
|
||||
```
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 1. 核心类
|
||||
- `ImageCacheManager`: 缓存管理器
|
||||
- `XiurenImagePlugin`: 主插件类
|
||||
|
||||
### 2. 关键方法
|
||||
- `get_cached_image_bytes()`: 获取缓存的图片bytes
|
||||
- `_refill_cache()`: 重新填充缓存
|
||||
- `_load_image_bytes()`: 从磁盘加载图片bytes
|
||||
|
||||
### 3. 数据结构
|
||||
```python
|
||||
{
|
||||
'path': str, # 图片文件路径
|
||||
'bytes': bytes # 图片的bytes数据
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 并发安全设计
|
||||
- **无锁实现**: 使用Python的deque数据结构,其操作本身是线程安全的
|
||||
- **原子操作**: deque的append和popleft操作是原子的
|
||||
- **避免死锁**: 去掉了显式的线程锁,避免了死锁问题
|
||||
- **异步填充**: 使用daemon线程进行异步填充,不会阻塞主流程
|
||||
|
||||
## 性能对比
|
||||
|
||||
### 优化前
|
||||
- 每次请求都需要从磁盘读取图片文件
|
||||
- 磁盘I/O成为性能瓶颈
|
||||
- 响应时间较长
|
||||
|
||||
### 优化后
|
||||
- 大部分请求直接从内存获取
|
||||
- 显著减少磁盘I/O操作
|
||||
- 响应时间大幅提升
|
||||
- 无锁设计,避免并发问题
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **内存使用**: 缓存会占用一定内存,建议根据服务器内存情况调整缓存大小
|
||||
2. **文件更新**: 如果图片文件被更新,需要重启插件或等待缓存刷新
|
||||
3. **错误处理**: 如果缓存失败,会自动回退到原来的磁盘读取方式
|
||||
4. **并发安全**: 使用deque的原子操作,支持并发访问,无需额外锁机制
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 1. 缓存不工作
|
||||
- 检查Redis连接是否正常
|
||||
- 确认图片目录是否存在且有读取权限
|
||||
- 查看日志中的错误信息
|
||||
|
||||
### 2. 内存占用过高
|
||||
- 减少 `cache_size` 配置值
|
||||
- 检查是否有内存泄漏
|
||||
|
||||
### 3. 图片获取失败
|
||||
- 检查图片文件是否完整
|
||||
- 确认文件格式是否支持
|
||||
- 查看磁盘空间是否充足
|
||||
|
||||
### 4. 性能问题
|
||||
- 如果出现卡死,检查是否有死锁问题
|
||||
- 确保异步填充线程正常工作
|
||||
- 监控缓存命中率
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.1.0
|
||||
- 去掉了线程锁,改用无锁设计
|
||||
- 修复了死锁问题
|
||||
- 提高了并发性能
|
||||
- 增加了更详细的错误处理
|
||||
Reference in New Issue
Block a user