知识卡片
会话表分段轮换清理策略(Kai Yu方案)
内容
把服务器会话状态序列化存进数据库表后,一个绕不开的问题是怎么清理那些已经作废的会话——常规思路是起一个监督进程定期扫描、找出过期会话并删除,但这样做意味着频繁对会话表做大量查询和删除操作,本身就是一笔不小的开销。Kai Yu提供了一个更巧妙的做法:把会话表拆成12个分段,每两小时轮换一次——轮换发生时,直接把时间最旧的那一段里的全部数据一次性删除清空,然后把接下来两小时内的新会话数据写入这个刚清空的分段。这个方案的代价是:任何存活超过24小时的会话都会被强制清理掉,但作者认为这种极端情况在实践中几乎不用担心。这个技巧的精妙之处在于把”逐条判断是否过期再删除”的高开销操作,转换成了”整体清空一个分段”的低开销操作——不需要针对每一条记录做时间戳比较,而是靠”分段+固定周期轮换”的结构设计,让”删除过期数据”这件事本身变得几乎零成本。可迁移启发:面对”大量记录里挑出符合某个时间窗口条件的子集去清理”这类问题,与其对每条记录逐一判断,不如考虑能否通过分桶/分段的结构设计,把”清理”这个动作转化成”整体丢弃一个桶”这种更廉价的操作——用可预测的、稍微牺牲一点精确性的批量操作,换取避免逐条扫描判断带来的持续性能开销,这个思路不局限于会话清理,也适用于日志滚动、缓存过期等类似场景。
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第17章 会话状态模式"之"17.2.1 运行机制"(源文件:_epub-src/OEBPS/Text/000206.html)
- 结论依据:原文说明"一种方法是用一个监督进程检查并删除过期的会话,但这样会造成很多与会话表的连接。Kai Yu提供了他使用的一个好方法:将会话表分成12段,每两个小时轮换一次,轮换时先删除时间最旧的段中所有的数据,并把所有新的数据放到该段中。虽然这样会把那些超过24个小时的会话强制删除,但实际上不用去担心这样极少数的情况",直接支撑本卡结论。
- 原始内容:Kai Yu提供了他使用的一个好方法:将会话表分成12段,每两个小时轮换一次,轮换时先删除时间最旧的段中所有的数据,并把所有新的数据放到该段中。