Redis与session使用及说明

 更新时间:2026年02月06日 15:43:32   作者:peachcobbler  
文章介绍了传统Session和Redis在分布式场景下存储Session的优缺点对比,指出Redis更适合替代传统Session,因为它提供了分布式共享、高效存储、持久化保障等优势

一、传统 Session:服务器内存中的用户状态容器

1. 本质与核心功能

Session(会话)是 Web 服务器(如 Tomcat)为解决 HTTP 协议 “无状态性” 而设计的 服务器端状态存储机制。其核心功能是:

  • 为每个用户生成唯一标识(sessionId),关联用户的连续请求;
  • 存储用户的临时状态信息(如登录状态、购物车数据、权限标识等),实现 “用户身份跟踪”。

2. 内部结构与核心属性

传统 Session(以 Java Web 的HttpSession为例)本质是 服务器内存中的一个 “键值对对象”,结构可拆解为:

属性 / 组件说明
sessionId唯一标识(字符串,如6F9619FF-8B86-D011-B42D-00C04FC964FF),由服务器随机生成,用于关联客户端请求。
attributes核心存储区(Map<String, Object>结构),存储用户数据(如userId=1001、username="张三"、cart={...})。
生命周期参数maxInactiveInterval:最大空闲时间(默认 30 分钟,超时自动失效);creationTime/lastAccessedTime:创建与最后访问时间,用于判断是否超时。
状态标识isNew():判断是否为新会话;isValid():判断会话是否有效(未过期 / 未销毁)。

3. 与 Tomcat 服务器的强绑定机制

传统 Session 的存储与管理完全依赖 单个 Web 服务器实例(如 Tomcat),具体表现为:

  • 存储位置:Session 数据保存在当前 Tomcat 进程的内存中(非磁盘),属于 “进程内数据”。
  • 管理主体:Tomcat 通过内置的SessionManager组件管理所有 Session,包括创建、查询、过期清理等(默认每 60 秒扫描一次过期 Session)。
  • 隔离性:不同 Tomcat 实例的内存相互独立,A 服务器的 Session 无法被 B 服务器访问(内存隔离是分布式场景的核心痛点)。

4. 生命周期(以用户登录为例)

创建:用户首次访问需要状态跟踪的接口(如登录)时,Tomcat 生成sessionId,创建 Session 对象并存储用户信息。

传递:服务器通过 HTTP 响应头的Set-CookiesessionId发送给客户端,客户端后续请求通过 Cookie 自动携带sessionId

活跃:用户持续操作时,Tomcat 通过sessionId找到对应 Session,更新lastAccessedTime(避免超时)。

过期 / 销毁

  • 超时:用户超过maxInactiveInterval未操作,Tomcat 自动销毁 Session;
  • 主动销毁:调用session.invalidate()(如用户退出登录);
  • 服务器重启:内存中的 Session 全部丢失(无持久化)。

5. 局限性(分布式场景下)

传统 Session 在单机应用中可行,但在分布式部署(多服务器集群)或高并发场景中存在致命问题:

  • 会话共享问题:用户请求被负载均衡分发到不同服务器时,新服务器无用户 Session,导致 “登录状态失效”(如用户在 Tomcat A 登录,下次请求到 Tomcat B 时被判定为未登录)。
  • 内存限制:Session 存储在服务器内存,用户量增长会导致内存占用飙升,甚至引发 OOM(内存溢出)。
  • 无持久化:服务器重启后 Session 全部丢失,用户需重新登录,体验极差。
  • 扩展性差:无法通过增加服务器节点分担 Session 存储压力(每个节点仍需存储全量 Session)。

二、Redis:分布式环境下的 Session 存储方案

Redis 是一款 高性能的分布式内存数据库,支持多种数据结构,通过网络提供服务,天生适合替代传统 Session 存储。

1. Redis 的核心特性(为何适合存储 Session)

  • 分布式访问:所有应用服务器(如 Tomcat 集群)可通过网络访问同一 Redis 实例(或集群),实现数据共享。
  • 高效存储:基于内存操作,读写性能极高(单机 QPS 可达 10 万 +),满足高并发场景。
  • 丰富数据结构:支持 String(字符串)、Hash(哈希)等结构,适配 Session 的键值对存储需求。
  • 原生过期机制:支持为 Key 设置过期时间,自动清理无效 Session,无需手动维护。
  • 持久化能力:通过 RDB(快照)或 AOF(日志)将数据持久化到磁盘,服务器重启后可恢复,避免数据丢失。

2. Redis 存储 Session 的结构设计

将 Session 数据迁移到 Redis 时,需设计合理的 Key 和 Value 结构,确保唯一性、可读性和高效性:

设计维度具体实现示例
Key 设计以sessionId或token(替代sessionId的唯一标识)为核心,添加业务前缀(便于管理和区分)。login:session:abc123(abc123为sessionId;login:session:为业务前缀)
Value 设计优先使用Hash 结构(适合存储多字段的用户信息,支持单独修改某字段);简单场景可用 String(存储 JSON 字符串)。Hash 结构:userId → "1001"username → "张三"loginTime → "2025-11-08 10:00:00"expire → "1800"(30 分钟,单位秒)
过期设置为 Key 设置与maxInactiveInterval一致的过期时间(如 30 分钟),Redis 自动删除过期 Key。EXPIRE login:session:abc123 1800(1800 秒后过期)

3. 工作流程(替代传统 Session 后)

  1. 用户登录:用户提交账号密码,服务器验证通过后生成唯一token(替代sessionId),将用户信息存入 Redis(Key 为login:session:token,Value 为 Hash 结构),并设置过期时间。
  2. 客户端存储:服务器将token返回给客户端(通常存入 Cookie 或 LocalStorage),客户端后续请求通过请求头(如Authorization: Bearer token)携带token。
  3. 请求验证:应用服务器(如 Tomcat)接收到请求后,从请求中提取token,通过 Redis 查询对应的用户信息:
    • 若存在:延长 Key 的过期时间(如重置为 30 分钟),允许访问;
    • 若不存在(过期或未登录):拦截请求,返回 “未登录” 提示。
  4. 用户退出:删除 Redis 中对应的 Key(DEL login:session:token),实现 “登出” 效果。

4. 优势(对比传统 Session)

  • 分布式共享:所有应用服务器通过 Redis 访问同一套 Session 数据,解决 “跨服务器登录状态失效” 问题。
  • 内存扩展:Redis 可独立部署,支持集群(分片 + 哨兵),存储容量可横向扩展(不受单个应用服务器内存限制)。
  • 持久化保障:RDB/AOF 机制确保 Session 数据在 Redis 重启后不丢失,用户无需重复登录。
  • 高效过期管理:Redis 的过期 Key 清理机制(惰性删除 + 定期删除)比 Tomcat 的内存扫描更高效,减少资源消耗。

三、传统 Session 与 Redis 存储 Session 的核心对比

维度传统 Session(Tomcat 内存)Redis 存储 Session
存储位置单个应用服务器(如 Tomcat)的内存中独立的 Redis 服务器(或集群)内存中
数据结构进程内的HttpSession对象(Map式键值对)Redis 的 Key-Value 对(Key 为token,Value 为 Hash/JSON)
访问范围仅当前应用服务器可访问(内存隔离)所有应用服务器通过网络访问(分布式共享)
生命周期管理依赖应用服务器(如 Tomcat 的SessionManager)依赖 Redis 的过期 Key 机制(自动清理)
持久化能力无(服务器重启后数据丢失)支持(RDB/AOF 持久化到磁盘)
扩展性差(受单个服务器内存限制,无法分布式扩展)好(Redis 集群可横向扩展,支持海量 Session)
高并发支持弱(内存占用高,清理效率低)强(内存数据库,读写性能优异,支持高 QPS)

四、为何用 Redis 替代传统 Session(以黑马点评为例)

黑马点评作为高并发的分布式电商项目,需解决以下核心问题,而 Redis 恰好适配:

  1. 分布式部署需求:项目需部署多台应用服务器(Tomcat 集群),传统 Session 的 “内存隔离” 会导致用户登录状态混乱,Redis 实现跨服务器会话共享。
  2. 高并发场景:秒杀、促销等场景下用户请求量激增,Redis 的高性能(毫秒级响应)可支撑大量 Session 读写,避免传统 Session 的内存瓶颈。
  3. 用户体验保障:Redis 持久化确保服务器重启后 Session 不丢失,用户无需重复登录;过期机制可灵活控制登录有效期(如 “7 天内免登录”)。
  4. 业务扩展:Redis 的 Hash 结构便于存储用户多维度信息(如会员等级、优惠券数量),后续业务扩展时无需修改存储结构,兼容性更强。

总结

传统 Session 是 “单机内存级” 的状态存储,依赖单个应用服务器,适合简单单机场景;而 Redis 是 “分布式级” 的状态存储,通过网络共享数据,支持高并发、高可用和弹性扩展,是分布式项目(如黑马点评)中替代传统 Session 的最优解。

其核心逻辑是:用独立的分布式存储打破 Session 与服务器的强绑定,解决分布式场景下的会话一致性问题

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Nacos配置中心集群原理及源码分析

    Nacos配置中心集群原理及源码分析

    这篇文章主要为大家介绍了Nacos配置中心集群原理及源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-03-03
  • Spring Boot如何处理@Resource示例分析

    Spring Boot如何处理@Resource示例分析

    这篇文章主要为大家介绍了Spring Boot如何处理@Resource示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • SpringBoot前后端分离项目之打包、部署到服务器详细图文流程

    SpringBoot前后端分离项目之打包、部署到服务器详细图文流程

    作为后台开发,项目打包部署是经常性的操作,下面这篇文章主要给大家介绍了关于SpringBoot前后端分离项目之打包、部署到服务器的相关资料,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • 使用mybatis-plus想要修改某字段为null问题

    使用mybatis-plus想要修改某字段为null问题

    这篇文章主要介绍了使用mybatis-plus想要修改某字段为null问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • Java实体类常用注解的用法

    Java实体类常用注解的用法

    这篇文章主要介绍了Java实体类常用注解的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Java中内存分配的几种方法

    Java中内存分配的几种方法

    本文主要介绍Java中几种分配内存的方法。我们会看到如何使用sun.misc.Unsafe来统一操作任意类型的内存。以前用C语言开发的同学通常都希望能在Java中通过较底层的接口来操作内存,他们一定会对本文中要讲的内容感兴趣
    2014-03-03
  • 使用Java实现希尔排序算法的简单示例

    使用Java实现希尔排序算法的简单示例

    这篇文章主要介绍了使用Java实现希尔排序算法的简单示例,希尔排序可以被看作是插入排序的一种更高效的改进版本,需要的朋友可以参考下
    2016-05-05
  • Java五子棋单机版源码分享

    Java五子棋单机版源码分享

    这篇文章主要为大家分享了Java五子棋单机版源码,JavaGUI编写单机版五子棋,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Java通过Callable实现多线程

    Java通过Callable实现多线程

    这篇文章主要介绍了Java通过Callable实现多线程,Callable的任务执行后可返回值,运行Callable任务可以拿到一个Future对象,Future表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并检查计算的结果,需要的朋友可以参考下
    2023-10-10
  • 在jmeter的beanshell中用java获取系统当前时间的简单实例

    在jmeter的beanshell中用java获取系统当前时间的简单实例

    这篇文章介绍了在jmeter的beanshell中用java获取系统当前时间的简单实例,有需要的朋友可以参考一下
    2013-09-09

最新评论