修复:P0+P1 生产稳定性和性能优化(6项)

P0 稳定性修复:
- 告警去重字典添加惰性清理机制,防止长时间运行内存溢出
- Redis 连接断开时显式 close() 后再置 None,防止文件描述符泄漏
- 截图消息 ACK 移至成功路径,失败消息留在 pending list 自动重试

P1 性能优化:
- GPU NMS 添加 torch.no_grad() + 显式释放临时张量,减少显存碎片
- 截图存储改为 Redis 原始 bytes,去掉 Base64 编解码开销(兼容旧格式)
- ROI 配置查询 N+1 改为 get_all_bindings() 单次 JOIN 查询

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 14:05:57 +08:00
parent a9a5457583
commit 5a0265de52
8 changed files with 593 additions and 41 deletions

View File

@@ -215,6 +215,15 @@ class ConfigSyncManager:
logger.error(f"本地 Redis 连接失败: {e}")
self._local_redis = None
def _safe_close_cloud_redis(self):
"""安全关闭云端 Redis 连接"""
if self._cloud_redis is not None:
try:
self._cloud_redis.close()
except Exception:
pass
self._cloud_redis = None
def _init_cloud_redis(self):
"""初始化云端 Redis 连接"""
try:
@@ -238,7 +247,7 @@ class ConfigSyncManager:
except Exception as e:
logger.warning(f"云端 Redis 连接失败(将使用本地缓存运行): {e}")
self._cloud_redis = None
self._safe_close_cloud_redis()
def _init_database(self):
"""初始化 SQLite 数据库连接"""
@@ -311,9 +320,7 @@ class ConfigSyncManager:
try:
cameras = self._db_manager.get_all_camera_configs()
rois = self._db_manager.get_all_roi_configs()
binds = []
for roi in rois:
binds.extend(self._db_manager.get_bindings_by_roi(roi["roi_id"]))
binds = self._db_manager.get_all_bindings()
logger.info(f"[EDGE] Loading config from local db ({source})...")
logger.info(f"[EDGE] Camera count = {len(cameras)}")
logger.info(f"[EDGE] ROI count = {len(rois)}")
@@ -378,7 +385,7 @@ class ConfigSyncManager:
if self._stop_event.is_set():
return
logger.warning(f"云端 Redis 连接断开: {e}, {backoff}s 后重连...")
self._cloud_redis = None
self._safe_close_cloud_redis()
self._stop_event.wait(backoff)
backoff = min(backoff * 2, max_backoff)
@@ -776,10 +783,7 @@ class ConfigSyncManager:
bindings_list = self._db_manager.get_bindings_by_camera(camera_id)
else:
roi_configs = self._db_manager.get_all_roi_configs()
bindings_list = []
for roi in roi_configs:
bindings = self._db_manager.get_bindings_by_roi(roi['roi_id'])
bindings_list.extend(bindings)
bindings_list = self._db_manager.get_all_bindings()
roi_dict = {r['roi_id']: r for r in roi_configs}
bindings_dict: Dict[str, list] = {}
@@ -857,8 +861,7 @@ class ConfigSyncManager:
binds: List[Dict[str, Any]] = []
rois = self._db_manager.get_all_roi_configs()
for roi in rois:
binds.extend(self._db_manager.get_bindings_by_roi(roi["roi_id"]))
binds = self._db_manager.get_all_bindings()
return binds
def get_algo_bind_from_redis(self, bind_id: str) -> Optional[Dict[str, Any]]: