一句话介绍:面向 MaiBot 的企业级全栈性能优化引擎,通过多级缓存体系、算法优化与运行时调优,实现 70-90% 数据库查询削减与 10-100 倍计算加速。
| 缓存体系 | 算法加速 | 运行时调优 | 监控告警 |
|---|---|---|---|
| 双缓冲切换 | 快速模糊匹配 | WAL Checkpoint | QQ/Console 通知 |
| 优化模块 | 性能提升 | 内存开销 | DB 查询削减 | 延迟改善 |
|---|---|---|---|---|
| message_cache | 减少 70-90% 重复查询 | ~50MB / 千条消息 | 70-90% | < 5ms (缓存命中) |
| person_cache | 减少 80% 数据库往返 | ~30MB / 千人 | 80% | < 1ms |
| expression_cache | 全量内存查询 | ~100MB | 100% (命中时) | < 0.1ms |
| jargon_cache | 10-100x 匹配加速 | ~20MB / 万条 | 100% | < 1ms |
| kg_cache | Parquet 序列化 5x 加速 | 可配置 | 按需加载 | < 10ms |
| levenshtein_fast | 10-50x 计算加速 | 极小 | N/A | 复杂度 O(n) |
| jargon_matcher_automaton | 100x+ 多模式匹配 | ~50MB | N/A | O(n) 线性 |
| image_desc_bulk_lookup | 批量查询 5-10x 加速 | 极小 | 批量替代循环 | 减少 N 次 RTT |
| message_repository_fastpath | 消息计数 3-5x 加速 | ~10MB | 缓存 COUNT | < 2ms |
| regex_precompile | 编译复用消除重复开销 | 极小 | N/A | 首次编译后 O(1) |
| typo_generator_cache | 缓存拼写错误生成结果 | ~10MB | N/A | 消除重复生成 |
| user_reference_batch_resolve | 减少重复 @ 解析 | ~5MB | 解析结果缓存 | < 5ms |
| db_tuning | SQLite 吞吐量提升 30-50% | N/A | WAL + mmap | I/O 优化 |
| lightweight_profiler | 零侵入性能观测 | < 1MB | N/A | 采样开销 < 0.1% |
备注:上述指标基于典型 MaiBot 工作负载测试,实际效果受数据规模、硬件配置和流量模式影响。
CM-Performance-Optimizer 采用 模块化分层架构,遵循以下核心原则:
- 非侵入式增强:通过 PatchChain 实现运行时方法拦截,不修改核心业务逻辑
- 优雅降级:核心功能不依赖任何可选库,缺失依赖时自动降级
- 线程安全:全面使用锁、原子操作与线程局部存储
- 生产就绪:健康检查、监控告警、错误恢复机制完备
┌─────────────────────────────────────────────────────────────────┐
│ CM-Performance-Optimizer │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ PatchChain │ │ TTLCache │ │ 双缓冲切换机制 │ │
│ │ 方法拦截 │ │ 过期淘汰 │ │ 分批加载+原子切换 │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ 14 个优化模块 ││
│ ├─────────────┬─────────────┬─────────────┬───────────────────┤│
│ │ 缓存模块 │ 算法加速 │ 数据库调优 │ 监控分析 ││
│ (5个) │ (4个) │ (2个) │ (2个) ││
│ └─────────────┴─────────────┴─────────────┴───────────────────┘│
└─────────────────────────────────────────────────────────────────┘
| 技术 | 应用场景 | 价值 |
|---|---|---|
| PatchChain | 运行时方法拦截 | 无侵入增强现有功能 |
| TTLCache | 缓存过期策略 | 内存友好、自动淘汰 |
| 双缓冲 (Dual Buffer) | 热数据更新 | 分批加载 + yield 让出 + 原子切换 |
| Aho-Corasick | 多模式字符串匹配 | O(n) 线性复杂度、100x+ 加速 |
| rapidfuzz | 编辑距离计算 | C 扩展 10-50x 加速 |
| Parquet | 知识图谱序列化 | 列式存储 5x I/O 加速 |
| WAL Mode | SQLite 读写优化 | 并发读写、减少锁竞争 |
| mmap | SQLite 内存映射 | 减少系统调用、提升大数据库性能 |
| 类别 | 模块数量 | 模块列表 |
|---|---|---|
| 缓存模块 | 5 | message_cache, person_cache, expression_cache, jargon_cache, kg_cache |
| 算法加速 | 4 | levenshtein_fast, jargon_matcher_automaton, regex_precompile, typo_generator_cache |
| 数据库优化 | 2 | db_tuning, message_repository_fastpath |
| 批量查询 | 2 | image_desc_bulk_lookup, user_reference_batch_resolve |
| 性能分析 | 1 | lightweight_profiler |
| 项目 | 说明 |
|---|---|
| 功能 | 缓存 find_messages 数据库查询结果,消除重复查询 |
| 关键技术 | TTLCache + 可选 orjson 加速序列化 + 双缓冲模式 |
| 配置参数 | per_chat_limit(50-1000), ttl(60-3600s), max_chats(100-2000), mode(query/full) |
| 性能收益 | 减少 70-90% 重复查询,缓存命中延迟 < 5ms |
| 内存估算 | ~50MB / 千条消息 |
| 降级机制 | 无 orjson 时自动回退到标准 json;缓存失败不影响原始查询 |
双缓冲模式:
query模式:仅缓存查询结果对象full模式:缓存完整消息数据(适用于高消息量场景)- 切换时采用分批加载 + yield 让出事件循环,最小化锁持有时间
| 项目 | 说明 |
|---|---|
| 功能 | 缓存 Person.load_from_database() 结果,避免重复数据库读取 |
| 关键技术 | TTLCache + 智能预热机制 |
| 配置参数 | max_size(500-10000), ttl(300-7200s), warmup_enabled, warmup_per_chat_sample, warmup_max_persons |
| 性能收益 | 减少 80% 数据库往返,首次访问延迟降低 90%+ |
| 内存估算 | ~30MB / 千人 |
| 降级机制 | 预热失败不影响正常加载;TTL 过期自动淘汰 |
预热机制:
- 启动时后台采样活跃聊天的历史消息
- 提取高频出现的人物并预加载到缓存
- 增量更新:记录最后活跃时间,仅预热最近出现的用户
| 项目 | 说明 |
|---|---|
| 功能 | 将所有表达式加载到内存,实现微秒级查询 |
| 关键技术 | 双缓冲 + 分批 yield + 原子切换 + 后台增量加载 |
| 配置参数 | batch_size(50-500), batch_delay(0.01-1.0), refresh_interval(600-86400s), max_items, max_memory_mb |
| 性能收益 | 100% 消除数据库查询(命中时),延迟 < 0.1ms |
| 内存估算 | ~100MB(取决于表达式数量) |
| 降级机制 | 后台刷新失败不影响现有缓存;提供 json-repair 修复极端脏数据 |
刷新策略:
- 增量刷新:每 10 分钟检查变化,仅更新差异部分
- 全量重建:每 24 小时完整重建索引
- 平滑切换:新缓存构建完成后原子替换旧缓存,构建期间分批 yield 让出事件循环
内存保护:
max_items:缓存最大条目数限制(默认 10000)max_memory_mb:缓存最大内存使用量(默认 200MB)- 超出限制时使用 heapq.nsmallest 批量淘汰 LRU 条目
| 项目 | 说明 |
|---|---|
| 功能 | 将所有黑话数据加载到内存,支持高速匹配 |
| 关键技术 | 双缓冲 + 内容索引 + Aho-Corasick 自动机 + 分批 yield |
| 配置参数 | batch_size(50-500), batch_delay(0.01-1.0), refresh_interval(600-86400s) |
| 性能收益 | 10-100x 匹配加速,延迟 < 1ms |
| 内存估算 | ~20MB / 万条黑话 |
| 降级机制 | 索引构建失败回退到线性扫描;可选内容索引加速 |
Aho-Corasick 自动机:
- 预处理所有黑话模式构建 AC 自动机
- 单次扫描 O(n) 完成所有模式匹配
- 相比朴素 O(m*n) 暴力匹配提升 100x+
| 项目 | 说明 |
|---|---|
| 功能 | 缓存知识图谱数据,支持 Parquet 高效序列化 |
| 关键技术 | 双缓冲 + 文件哈希校验 + Parquet 列式存储 + 分批 yield |
| 配置参数 | batch_size(50-500), batch_delay(0.01-1.0), refresh_interval(600-86400s), use_parquet |
| 性能收益 | 5x I/O 性能提升,按需加载减少内存占用 |
| 内存估算 | 可配置(按需加载) |
| 降级机制 | Parquet 不可用时回退到 JSON;文件损坏自动降级到数据库查询 |
Parquet 优势:
- 列式存储:仅读取需要的列,减少 I/O
- 压缩率高:相比 JSON 节省 50-80% 存储空间
- 快速聚合:列式计算加速统计查询
| 项目 | 说明 |
|---|---|
| 功能 | 使用 rapidfuzz C 扩展替代纯 Python 实现编辑距离计算 |
| 关键技术 | SIMD 加速 + 多线程并行 |
| 可选依赖 | rapidfuzz >= 3.0.0 |
| 性能收益 | 10-50x 计算加速 |
| 降级机制 | 未安装 rapidfuzz 时回退到标准库 difflib |
适用场景:
- 模糊匹配
- 拼写纠错
- 相似度计算
| 项目 | 说明 |
|---|---|
| 功能 | 使用 Aho-Corasick 自动机实现多模式并行匹配 |
| 关键技术 | AC 自动机 + 失败函数预处理 |
| 可选依赖 | pyahocorasick >= 2.0.0 |
| 性能收益 | 100x+ 多模式匹配加速 |
| 降级机制 | 未安装时回退到正则表达式匹配 |
技术原理:
- KMP 算法的多模式扩展
- 构建确定性有限状态自动机 (DFA)
- 单次扫描同时匹配所有模式
| 项目 | 说明 |
|---|---|
| 功能 | 预编译常用正则表达式,消除重复编译开销 |
| 关键技术 | 编译结果缓存 + 模块级注册表 |
| 性能收益 | 首次编译后 O(1) 复用 |
| 降级机制 | 无 |
使用方式:
from core.utils import get_compiled_regex
# 预编译正则
pattern = get_compiled_regex(r"\d+")
result = pattern.match("abc123")| 项目 | 说明 |
|---|---|
| 功能 | 缓存拼写错误生成结果,避免重复计算 |
| 关键技术 | TTLCache + 记忆化 |
| 配置参数 | max_size, ttl |
| 性能收益 | 消除重复生成开销 |
| 内存估算 | ~10MB |
| 项目 | 说明 |
|---|---|
| 功能 | 自动配置 SQLite 运行时参数,优化 I/O 性能 |
| 关键技术 | PRAGMA 配置 + 索引自检 |
| 配置参数 | mmap_size(0+), wal_checkpoint_interval(0-86400s) |
| 性能收益 | 吞吐量提升 30-50% |
优化参数:
PRAGMA journal_mode=WAL; -- 预写日志模式
PRAGMA synchronous=NORMAL; -- 平衡安全与性能
PRAGMA cache_size=-64000; -- 64MB 缓存
PRAGMA mmap_size=268435456; -- 256MB 内存映射
PRAGMA temp_store=MEMORY; -- 临时表存内存WAL Checkpoint:
- 定期执行
PRAGMA wal_checkpoint(TRUNCATE) - 控制写入频率,防止 WAL 文件无限增长
- 可配置检查间隔 (默认 300s)
| 项目 | 说明 |
|---|---|
| 功能 | 缓存消息计数结果,消除重复 COUNT 查询 |
| 关键技术 | COUNT 缓存 + 短 TTL |
| 配置参数 | ttl(30-300s) |
| 性能收益 | 3-5x 加速 |
| 内存估算 | ~10MB |
| 项目 | 说明 |
|---|---|
| 功能 | 批量查询图片描述,用 WHERE IN 替代循环单条查询 |
| 关键技术 | 批量拼接 + 数据库往返削减 |
| 性能收益 | 5-10x 加速(减少 N-1 次 RTT) |
| 降级机制 | 批量失败时回退到逐条查询 |
| 项目 | 说明 |
|---|---|
| 功能 | 缓存 @用户引用解析结果,减少重复解析 |
| 关键技术 | TTLCache + 批量解析 |
| 配置参数 | ttl, max_size |
| 性能收益 | 减少重复解析开销 |
| 内存估算 | ~5MB |
| 项目 | 说明 |
|---|---|
| 功能 | 可开关的纯观测层 SQL 性能分析 |
| 关键技术 | 采样统计 + 开销极低的插桩 |
| 配置参数 | sample_rate(0.0-1.0) |
| 性能收益 | 采样开销 < 0.1% |
| 可选依赖 | psutil >= 5.9.0 |
特性:
- 零侵入:不影响正常业务流程
- 可开关:生产环境可关闭
- 采样友好:可配置采样率控制开销
| 要求 | 最低版本 | 说明 |
|---|---|---|
| MaiBot | >= 0.12.0 | 推荐使用最新 main 分支 |
| Python | >= 3.8 | |
| 内存 | >= 1GB | 根据数据量调整 |
# 1. 克隆插件到 MaiBot plugins 目录
cd MaiBot/plugins
git clone https://github.com/chengmoya/CM-performance-optimizer-plugin.git
# 2. 安装依赖(可选依赖,未安装时自动降级)
cd CM-performance-optimizer-plugin
uv pip install -r requirements.txt
# 3. 重启 MaiBot
# 配置文件会自动生成到 MaiBot/data/plugins/CM-performance-optimizer/config.toml提示:大部分依赖为可选依赖,未安装时插件仍可正常运行,对应增强模块会自动降级或禁用。
# MaiBot/data/plugins/CM-performance-optimizer/config.toml
[plugin]
enabled = true
log_level = "INFO"
[modules]
message_cache_enabled = true
person_cache_enabled = true
expression_cache_enabled = true
jargon_cache_enabled = true
kg_cache_enabled = false # 需要额外依赖# 生产环境推荐配置
[plugin]
enabled = true
log_level = "WARNING"
[modules]
# 开启所有缓存模块
message_cache_enabled = true
person_cache_enabled = true
expression_cache_enabled = true
jargon_cache_enabled = true
kg_cache_enabled = true
levenshtein_fast_enabled = true
jargon_matcher_automaton_enabled = true
message_repository_fastpath_enabled = true
[message_cache]
per_chat_limit = 500
ttl = 600
max_chats = 1000
mode = "full"
[person_cache]
max_size = 5000
ttl = 3600
warmup_enabled = true
warmup_per_chat_sample = 50
warmup_max_persons = 30
[expression_cache]
refresh_interval = 3600
incremental_refresh_interval = 600
batch_size = 100
batch_delay = 0.05
max_items = 10000
max_memory_mb = 200
[jargon_cache]
enable_content_index = true
refresh_interval = 3600
batch_size = 100
batch_delay = 0.05
[kg_cache]
use_parquet = true
refresh_interval = 7200
batch_size = 100
batch_delay = 0.05
[db_tuning]
mmap_size = 536870912 # 512MB
wal_checkpoint_interval = 300
[notification]
enabled = true
admin_qq = "123456789" # 替换为管理员 QQ# 高并发场景配置
[plugin]
enabled = true
log_level = "INFO"
[modules]
# 全量开启
message_cache_enabled = true
person_cache_enabled = true
expression_cache_enabled = true
jargon_cache_enabled = true
kg_cache_enabled = true
levenshtein_fast_enabled = true
jargon_matcher_automaton_enabled = true
image_desc_bulk_lookup_enabled = true
message_repository_fastpath_enabled = true
regex_precompile_enabled = true
user_reference_batch_resolve_enabled = true
[message_cache]
per_chat_limit = 1000
ttl = 1800
max_chats = 2000
mode = "full"
ignore_time_limit_when_active = true
active_time_window = 600
[person_cache]
max_size = 10000
ttl = 7200
warmup_enabled = true
[db_tuning]
mmap_size = 1073741824 # 1GB
wal_checkpoint_interval = 60
[monitoring]
enable_stats = true
stats_interval = 30
enable_memory_monitor = true
memory_warning_threshold = 0.75
memory_critical_threshold = 0.9# 资源受限环境配置
[plugin]
enabled = true
log_level = "WARNING"
[modules]
message_cache_enabled = true
person_cache_enabled = true
expression_cache_enabled = false # 关闭,节省 ~100MB
jargon_cache_enabled = true
kg_cache_enabled = false # 关闭
lightweight_profiler_enabled = false # 关闭
[message_cache]
per_chat_limit = 50
ttl = 120
max_chats = 100
mode = "query"
[person_cache]
max_size = 500
ttl = 600
warmup_enabled = false
[monitoring]
enable_memory_monitor = true
memory_warning_threshold = 0.7
memory_critical_threshold = 0.85# 调试和问题排查配置
[plugin]
enabled = true
log_level = "DEBUG"
[modules]
lightweight_profiler_enabled = true
[lightweight_profiler]
sample_rate = 0.5 # 50% 采样
[monitoring]
enable_stats = true
stats_interval = 10 # 每 10 秒输出统计
enable_health_check = true
health_check_interval = 10每个优化模块都有独立开关,可根据实际需求选择性启用:
[modules]
# 仅启用缓存,不启用算法加速
message_cache_enabled = true
person_cache_enabled = true
expression_cache_enabled = true
# 关闭不需要的模块
kg_cache_enabled = false
lightweight_profiler_enabled = false针对冷启动场景,可配置预热策略加速首次访问:
[person_cache]
warmup_enabled = true
warmup_per_chat_sample = 30 # 每聊天采样 30 条消息
warmup_max_persons = 20 # 最多预热 20 人
warmup_ttl = 120 # 预热记录有效期
warmup_debounce_seconds = 3.0 # 防抖时间表达式、黑话、知识图谱等大缓存支持平滑热更新,通过分批处理避免事件循环阻塞:
[expression_cache]
refresh_interval = 3600 # 全量刷新间隔(秒)
incremental_refresh_interval = 600 # 增量刷新间隔(秒)
batch_size = 100 # 每批加载条目数(50-500)
batch_delay = 0.05 # 批次间延迟秒数(0.01-1.0)
max_items = 10000 # 缓存最大条目数
max_memory_mb = 200 # 缓存最大内存(MB)
[jargon_cache]
refresh_interval = 3600
batch_size = 100
batch_delay = 0.05
enable_content_index = true # 启用内容索引加速
[kg_cache]
refresh_interval = 7200
batch_size = 100
batch_delay = 0.05
use_parquet = true # 使用 Parquet 格式加速 I/O配置参数说明:
| 参数 | 类型 | 默认值 | 范围 | 说明 |
|---|---|---|---|---|
batch_size |
int | 100 | 50-500 | 每批加载的条目数,影响内存峰值 |
batch_delay |
float | 0.05 | 0.01-1.0 | 批次间延迟秒数,让出事件循环 |
max_items |
int | 10000 | 1+ | 缓存最大条目数(仅 expression_cache) |
max_memory_mb |
int | 200 | 1+ | 缓存最大内存 MB(仅 expression_cache) |
refresh_interval |
int | 3600 | 60-86400 | 全量刷新间隔秒数 |
[db_tuning]
mmap_size = 536870912 # 256MB 内存映射
wal_checkpoint_interval = 300 # 每 5 分钟 checkpoint[monitoring]
enable_stats = true
stats_interval = 60
enable_memory_monitor = true
memory_warning_threshold = 0.8
memory_critical_threshold = 0.9
enable_health_check = true
health_check_interval = 30
[notification]
enabled = true
admin_qq = "123456789"PatchChain 是本插件的核心基础设施,实现方法级别的运行时拦截:
from core.patch_chain import PatchChain, patch_method
# 拦截数据库查询方法
original_find_messages = MessageRepository.find_messages
def patched_find_messages(self, query):
# 检查缓存
cache_key = generate_cache_key(query)
if cache_key in message_cache:
return message_cache[cache_key]
# 调用原始方法
result = original_find_messages(self, query)
# 存入缓存
message_cache[cache_key] = result
return result
# 注册补丁
patch_method(MessageRepository, 'find_messages', patched_find_messages)大缓存更新采用双缓冲设计,通过分批加载 + yield 让出 + 原子切换实现平滑更新:
class DualBuffer:
def __init__(self):
self._buffer_a = {} # 当前活跃缓存
self._buffer_b = {} # 后台构建缓存
self._using_a = True
self._yield_batch_size = 500 # 每 500 条让出事件循环
async def update(self, new_data):
# 后台分批构建新缓存
for i in range(0, len(new_data), self._yield_batch_size):
batch = new_data[i:i + self._yield_batch_size]
self._buffer_b.update(self._build_batch(batch))
await asyncio.sleep(0) # 让出事件循环,保持响应
# 原子切换(锁内仅赋值)
with self._lock:
self._buffer_a, self._buffer_b = self._buffer_b, {}
self._using_a = not self._using_a
def get_active(self):
return self._buffer_a if self._using_a else self._buffer_b核心优化策略:
| 策略 | 说明 | 效果 |
|---|---|---|
| 分批处理 | 大规模数据按 batch_size 分批加载 |
避免长时间阻塞 |
| yield 让出 | 每批处理后 await asyncio.sleep(0) |
事件循环保持响应 |
| 锁最小化 | 重操作在锁外完成,锁内仅原子赋值 | 缩短锁持有时间 |
| O(n log k) 淘汰 | 使用 heapq.nsmallest 替代 O(n²) 扫描 |
大规模淘汰加速 |
插件在任何依赖缺失时都能正常运行:
| 缺失依赖 | 受影响模块 | 降级行为 |
|---|---|---|
| orjson | message_cache | 回退到标准 json |
| rapidfuzz | levenshtein_fast | 回退到 difflib |
| pyahocorasick | jargon_matcher_automaton | 回退到正则 |
| pandas/pyarrow | kg_cache | 回退到 JSON |
| psutil | lightweight_profiler | 模块禁用 |
- 缓存操作:使用
threading.RLock保护 - 计数器:使用
atomic操作或锁 - 配置更新:使用
threading.Event触发热更新 - 后台任务:使用
concurrent.futures.ThreadPoolExecutor
- 健康检查:定时检测各模块状态
- 错误恢复:异常捕获不影响主流程
- 配置校验:启动时验证参数合法性
- 日志分级:DEBUG/INFO/WARNING/ERROR/CRITICAL
可能原因:缺少可选依赖
解决方案:
# 安装所有可选依赖
uv pip install -r requirements.txt
# 或仅安装特定依赖
pip install rapidfuzz pyahocorasick pandas pyarrow psutil可能原因:
- 模块未启用
- 缓存 key 不匹配
- TTL 过短
解决方案:
# 检查配置
[modules]
message_cache_enabled = true
[message_cache]
ttl = 600 # 确保 TTL 足够长
# 查看日志
log_level = "DEBUG"可能原因:缓存配置过大
解决方案:
# 减小缓存
[message_cache]
per_chat_limit = 50
max_chats = 100
[person_cache]
max_size = 500可能原因:
- 数据量较小
- 未启用算法加速模块
- 硬件瓶颈
解决方案:
# 启用所有加速模块
[modules]
levenshtein_fast_enabled = true
jargon_matcher_automaton_enabled = true
# 调整数据库参数
[db_tuning]
mmap_size = 536870912| 场景 | 推荐日志级别 |
|---|---|
| 生产环境 | WARNING |
| 调试 | DEBUG |
| 监控 | INFO |
本项目采用 MIT 许可证,详见 LICENSE 文件。
- 插件仓库:https://github.com/chengmoya/CM-performance-optimizer-plugin
- MaiBot 主项目:https://github.com/Mai-with-u/MaiBot
- MaiBot 开发文档:https://docs.mai-mai.org/develop/
CM-Performance-Optimizer © 2024-2026 by 城陌
让 MaiBot 飞起来 🚀