知识卡片

Cookie-Session服务端状态管理面临集群水平扩展的CAP三选一

普通读书笔记卡

内容

HTTP协议本身无状态,但认证授权天然需要”记住你是谁”,Cookie-Session机制 补上了这一环:服务端把用户上下文存在自己内存里,只在Cookie中传一个无 意义的SessionID作为查找Key。这个方案在安全性上有先天优势——敏感信息 始终留在服务端,Cookie里泄漏的只是一个索引;而且服务端有主动管理能力, 可以随时修改或清除任意用户的上下文(比如强制某用户下线)。但一旦要 水平扩展到集群,Session存在单机内存里这件事就成了麻烦——本质上是CAP 定理在”跨节点共享Session状态”这件小事上的又一次体现,只能三选二:牺牲 一致性,用亲和式负载均衡把同一用户固定分配到同一节点,代价是节点崩溃 时那部分用户的状态全部丢失;牺牲可用性,用复制式Session把每次变更组播 同步到所有节点,代价是节点越多同步成本越高;牺牲分区容忍性,把Session 集中存到一个所有节点都能访问的数据节点(如Redis),代价是这个数据节点 本身成了单点。这也是为什么[[JWT用签名取代服务端状态解决分布式认证问题 及其代价]]会在分布式场景下重新被拾起——不是JWT比Cookie-Session先进, 而是JWT从根源上不需要”跨节点共享状态”这件事。

参考来源

- 位置:《凤凰架构:构建可靠的大型分布式系统》第5章"架构安全性" 5.3.1节"Cookie-Session"(源文件:_epub-src对应OEBPS/Text/chapter64.xhtml) - 结论依据:原文说明Session存储在服务器内存中,水平扩展时必须在牺牲 一致性(亲和式负载均衡)、牺牲可用性(复制式Session)、牺牲分区容忍性 (集中式数据节点)三者间选择,并指出这是CAP定理在分布式状态管理上的 体现,直接支撑本卡片结论。 - 原始内容:由于Session存储在服务器的内存中,当服务器水平拓展成多节点 时,设计者必须在以下三种方案中选择其一……只要在分布式系统中共享信息, CAP就不可兼得,所以分布式环境中的状态管理一定会受到CAP的限制。