0%

springSession数据结构

文章字数:721,阅读全文大约需要2分钟

三种redis中保存session的key

  1. spring:session:sessions:sessionId
  2. spring:session:expirations:时间戳
  3. spring:session:sessions:expires:sessionId

spring:session:是三个键公用的前缀

sessions

spring:session:sessions:sessionId的数据类型是hash类型,其中保存着session相关信息和session的数据。默认TTL是35分钟

1
2
3
4
"lastAccessedTime": 1523933008926,/*2018/4/17 10:43:28*/    #最后访问时间
creationTime": 1523933008926, /*2018/4/17 10:43:28*/ #创建时间
maxInactiveInterval": 1800, #失效时长
sessionAttr:xxx:"666" #session的值 sessionAttr:名字:“值”

expirations:

  1. redis的过期处理优先级很低,如果有很多过期的键就会出现键已经过期但是未删除
  2. 确保redis的键过期的方式有两个:访问过期的键、手动删除
  3. 基于以上两点,spring会定时手动清除过期的键。
    spring:session:expirations:时间戳中保存的数据为set类型,其中保存着时间戳所在的一分钟之内过期的session,有数据访问就移除,添加到下一个时间段的set中。使用专门的键保存过期需要确保删除的session可以避免全局查找,然后一个个访问失效时间等信息。
    用户快速操作可能会带来并发问题,在两个时间段都进行了请求。session的过期时间应该向后推两次,但是可能第一次向后推还没完成第二次就完成了(两次操作处于时间段节点)这样就造成session过期时间存在于两个时间段中。
    此时如果直接删除会造成时间差,比预计删除早了一分钟。所以不能使用删除,使用hasKey命令访问过期的key,让redis自动删除。

sessions:expires

spring:session:sessions:expires:sessionId的值为空,sessions中保存着session的具体值,sessions:expires则是代表session的有效时间。
spring需要在知道session过期后拿到过期session的详细信息并进行操作。然而redis的键空间通知keyspace notifications只会说明那个键过期了,无法访问过期的键。于是设置了sessions:expires代表session过期时间,这个键过期了代表session过期。存储信息的sessions键则多存活5分钟,以便过期后访问信息。
spring中监听过期事件:

1
2
3
4
# 配置
org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction
# 过期事件
SessionExpiredEvent