session/cache 过期如何实现?

naive的做法是,一个单独线程定时遍历map,检查是否过期,开销大。

优化的思路是,按过期时间排序,只检查最老的是否过期。

1)一个辅助堆,comparator是到期时间,用最小堆。堆顶总是最老的session。但是这个堆必须支持更新任意位置元素,并且shift down(因为更新只可能把过期时间推后,所以肯定比parent更大,只需要往下看,shift down)。查找最老session是O(1)的,如果过期删除,需要调整堆,是O(lgn)。

2)一个辅助map(stl的map,红黑树),跟用最小堆的的思路类似。key是过期时间,value是session,也是根据过期时间排了序的,只不过每次找到最老的session的操作是O(lgn)的。更新session过期时间的操作是,先用老的过期时间在map里查找到 session,然后删除这个节点,更新过期时间,再插回去。这里有一个前提就是,每个session的过期时间都是不同的,所以时间要用粒度很细的时间,但实际中过期时间不需要卡这么细,这是这一方案的缺点。

3)一个辅助双向链表,类似LRU的思路。每次被访问的session移出并放到队尾,队头永远是最老的session。


还有一个问题,就是什么时候去check并移除过期的session,当然也可以用一个独立的线程定时去看,比naive的方案好在不需要遍历,只看看头一个或者几个。也可以每次访问session的时候去看,反正查看最老session是否过期是一个O(1)的操作,即使需要移除也只是O(1)或者O(lgn)的操作。或者用一个timing恰好的定时器去看,比如当前最老session还有10分钟过期,那么time的interval设成10分钟,10分钟后再醒来去检查,然后根据新的最老的过期时间设需要sleep的时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值