您的位置:首页 > 其它

神奇的闪电缓存,带系统飞

2021-02-01 23:59 316 查看

不羡鸳鸯不羡仙,一行代码调半天。原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

缓存,在高并发的应用中,用的那是相当多。为什么?就因为I/O实在是慢!为了解决不同组件之间的速度差,大家都寄希望于加入一个中间层,期待产生一些魔幻的事。

就拿Redis来说,火的就一塌糊涂,但中间会产生很多数据同步和数据一致性问题。有的牛x公司嫌烦,同时有钱,干脆干掉缓存后面的DB,直接把所有的数据放在了缓存上。哦不,这时候缓存已经不叫做缓存,应该叫做快存,因为它最终是要通过rdb落地的。

看到这里,先不要怀疑事实的正确性。有些公司的业务,确实不需要什么关系型数据库,一个redis就能玩得转。

闪电缓存场景

那闪电缓存又是何方神圣?实在不好意思, 这个名词,是xjjdog自创的。

它用在下面的场景之中。

一份数据,通过耗时的请求获取之后,会在极短的时间内,再次被用到。
业务对数据的一致性要求不是特别强烈,但也不是无底线忍受。
内存的空间有限,不适合把大量数据放在内存中。
数据的使用跨方法、跨代码块、甚至跨线程,只在时间概念上有关联
这个时候,我们就可以将数据缓存一小段时间,尽量在下次的使用的时候,从这个时间极短的缓存中获取。

srping-data-jpa背后的Hibernate一级缓存,在同一session下的数据被自动缓存,可以变相的看作是闪电缓存的一种实现。不过人家叫一级缓存,显得更高大上一些,应用也更局限一些。

Java有多种缓存数据的方法,也有不同的生命周期。你可以想一下Session中的数据该如何存取,也可以想一下Java框架中各种各样的Context,都是为了共享数据。

实现方式
闪电缓存,在Java中其实是有多种方式的,也有各种各样的优缺点。

ThreadLocal
第一种方式,就是ThreadLocal。拿最常用的Spring来说,它事务管理的传播机制,就是使用ThreadLocal实现的。

我可以在数据第一次被获取的时候,使用set方法给它设置一个值。然后在最后一个操作用的使用,把它remove掉,变相的实现请求级别的闪电缓存。(为什么要remove?因为在线程池中可能会有复用的问题)

但由于ThreadLocal是线程私有的,所以它不能够跨线程。上面Spring的事务传播机制是不能够跨线程的,我们的闪电缓存也是不能够跨线程的。

要想做到线程透传,也不是不可能。可以参照xjjdog以前的一篇文章。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: