前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >神奇的闪电缓存,带系统飞

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

作者头像
xjjdog
发布2020-11-02 10:49:01
8230
发布2020-11-02 10:49:01
举报
文章被收录于专栏:架构专题

缓存,在高并发的应用中,用的那是相当多。为什么?就因为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以前的一篇文章。

?《ThreadLocal局部变量透传》

这就决定了ThreadLocal的应用场景有限。但它还有其他两个硬伤:

  1. ThreadLocal的生命周期不好管理,何时生成,何时销毁,都是问题
  2. ThreadLocal使用自定义的ThreadLocalMap。它虽然叫Map,但却没有实现Map的接口,它使用开放寻址(遇到冲突,依次查找,直到空闲位置)的方法,这种方式是非常低效的

综上三点,ThreadLocal这个方案其实并不太好。

普通Cache加过期时间

我们可以变换一下思路,使用普通的Cache,然后给它一个超短的缓存时间,那么就可以变相的实现闪电缓存的功能。

实现也是非常简单的。比如,下面几行代码,就是一个对对象缓存了3秒的例子。

代码语言:javascript
复制
LoadingCache<String, String> lc = CacheBuilder
      .newBuilder()
      .expireAfterWrite(3,TimeUnit.SECONDS)
      .build(new CacheLoader<String, String>() {
      @Override
      public String load(String key) throws Exception {
            return slowMethod(key);
      }});

在这3秒之间,系统中所有用到这个数据的请求,都可以达到复用的效果。这对于并发量非常高的应用来说,减少的请求量可能是数量级的。

我曾经就做过一个对用户基本信息的优化,把对用户服务的请求量从8w/s,降低到1000/s,一度让负责服务的同学以为上游业务当机了。

End

技术通常都是工具,只有真正用到业务场景中,才有它的价值。闪电缓存这个概念本身没有什么神奇的,它的最优实现方式,竟然是普通的Cache加极短的过期时间。

技术本身是件非常简单的事情,但想到它应用的场景,却是比较难的。事实上,我已经把这个概念做到了我的ppt上,展现的时候大家比较迷惑,以为是什么高大上的东西,我自热也不好意思戳破这层窗户纸,就让它继续神秘下去吧。

如今xjjdog告诉你了,要保密哦。

推荐阅读:

一杯苦咖啡 | 公司来了个漂亮女实习程序员 失联的架构师,只留下一段脚本 架构师写的BUG,非比寻常 nginx工程师,需要上承天命,下召九幽 实力解剖一枚挖矿脚本,风骚操作亮瞎双眼 又一P1故障,锅比脸圆 传统企业的人才们,先别忙着跳“互联网”! 面试官很牛,逼我尿遁 又一批长事务,P0故障谁来背锅? 一天有24个小时?别开玩笑了! 《程序人生》杀机! 可怕的“浏览器指纹”,让你在互联网上,无处可藏 2w字长文,让你瞬间拥有「调用链」开发经验 996的乐趣,你是无法想象的 作为高级Java,你应该了解的Linux知识(非广告) 必看!java后端,亮剑诛仙(最全知识点) 学完这100多技术,能当架构师么?(非广告) Linux上,最常用的一批命令解析(10年精选) 数百篇「原创」文章,助你完成技术「体系化」

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小姐姐味道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 闪电缓存场景
  • 实现方式
    • ThreadLocal
      • 普通Cache加过期时间
      • End
      相关产品与服务
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档