LangGraph 用 MemorySaver 跑线上服务,4 小时内存从 1.2GB 涨到 6GB,thread_id 每条会话一个,历史快照全部驻留不释放。
一开始怀疑是「没有清理过期会话的策略」,查了一圈,方向不对。
把日志和配置对完,能解释这个现象的基本就这几处。MemorySaver 把所有快照放在进程内存里。少数情况下是每个 superstep 都会写一份状态快照。
还有一种情况,消息列表本身随轮次线性增长。
上来先统计当前 thread 数量与内存占比
python -c "import psutil;print(psutil.Process().memory_info().rss/1024/1024)"
随后换成 PostgresSaver 把状态落到库
python -c "from langgraph.checkpoint.postgres import PostgresSaver;print(PostgresSaver)"
接着按天清理超过 7 天的 thread
python -c "print('delete from checkpoints where created_at < now() - interval 7 day')"
给状态里的消息列表加上限并压测内存
python -c "print({'max_messages':30,'trim':'drop_oldest'})"
白天有业务在跑,能验证的部分都压到了晚上做。
当时还开着另一个排查窗口,两边日志对照着看才定位到。
改完先别撤,确认这几项。连续跑 4 小时内存稳定在 1.5GB 左右,thread 数量不再无限增长。
这里还有个坑。会话状态别放在进程内存里,落库加清理策略是标配,否则上线时间越长越危险。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
