转载

【极客源码】JetCache源码(一)开篇

【极客源码】JetCache源码(一)开篇
Java极客  |  作者  /  铿然一叶
这是 Java极客 的第 70 篇原创文章

相关阅读:

JAVA基础(一)简单、透彻理解内部类和静态内部类

JAVA基础(二)内存优化-使用Java引用做缓存

JAVA基础(三)ClassLoader实现热加载

JAVA基础(四)枚举(enum)和常量定义,工厂类使用对比

JAVA基础(五)函数式接口-复用,解耦之利刃

JAVA编程思想(一)通过依赖注入增加扩展性

JAVA编程思想(二)如何面向接口编程

JAVA编程思想(三)去掉别扭的if,自注册策略模式优雅满足开闭原则

JAVA编程思想(四)Builder模式经典范式以及和工厂模式如何选?

HikariPool源码(二)设计思想借鉴

人在职场(一)IT大厂生存法则

1. 为什么是JetCache

  1. 集成了Caffeine和Redis这两个比较著名的开源缓存工具
  2. 文档比较详细且更新频率较高
  3. 阿里开源缓存工具,且阿里内部也在使用
  4. 代码不复杂,比较容易阅读
  5. 有测试用例,方便调试

2. 带着缓存知识点看源码

JetCache作为一个缓存工具,应具备缓存工具应有的能力,同时要能解决缓存的常见问题,带着缓存的相关知识点来看JetCache的源码,并对比知识点,这样收获更大。缓存的核心知识点如下:

【极客源码】JetCache源码(一)开篇

2.1. 缓存应用场景

缓存应用场景主要有:

  • 减少数据库IO占用
  • 数据库连接数通常是有限的,如果并发请求数超过最大连接数,则会导致数据库无法访问,造成业务失败,因此可以将部分数据缓存起来,从而减少数据库访问。

  • 减少CPU占用
  • 对于一些需要消耗CPU计算,又会多次用到的数据也可以缓存起来,减少CPU消耗。

    2.2. 缓存分类

    2.2.1. 作用范围分类

    缓存从作用范围可以分为:

  • 线程级缓存
  • 例如数据库连接可通过线程内缓存传递,而不是通过方法参数传递,再比如业务比较复杂时,完整的业务流程要通过各个子流程串起来,每个子流程会访问相同的数据,会哪些相同数据事先并不知道,此时使用线程内缓存,就可以避免各个子流程因通过参数传递数据而耦合,只需将访问过的数据放入线程级缓存,后面的子流程就可以轻松访问,做到低耦合的同时还减少了数据库访问,提高了性能。

    线程级缓存在Java中可对应ThreadLocal存储的数据。

  • 进程级缓存
  • 进程内共享缓存,所有线程可见。

    进程级缓存在如JAVA中可对应静态变量存储的数据。

  • 分布式缓存
  • 在微服务架构下,多台微服务主机均使用各自的进程内缓存会占用更多内存,同时也会出现数据一致性问题,需要使用独立的分布式缓存来缓存数据。

    2.2.2. Java缓存分类

    Java中的缓存可以分为三类:

  • 强引用缓存
  • 对象具有强引用,不会被垃圾回收,即使发生OutOfMemoryError。

  • 软引用缓存
  • 对象具有软引用,在内存空间足够时,垃圾回收器不会回收它;当内存空间不足时,就会回收这些对象。

  • 弱引用缓存
  • 对象具有弱引用,垃圾回收时如果发现了它就会被回收,而不管内存是否足够。

    对于内存吃紧的主机,可以将不是频繁访问的缓存设置为软引用或者弱引用缓存,当需要内存时进行自动回收。

    2.3. 缓存设计

    缓存设计考虑的点有:

  • 失效策略
  • 根据不同的应用场景使用不同的失效策略,例如先进先出,先进后出,最近最少使用等等。

  • 序列化
  • 对于分布式缓存,需要考虑序列化策略,避免版本升级后序列化后的缓存不可用。

  • 缓存监控
  • 监控缓存的访问情况,命中率,热点等等,优化缓存。

  • 多级缓存
  • 考虑是否使用多级缓存提高可靠性。

    2.4. 常见问题

    使用或者开发一个缓存工具,需要考虑缓存的常见问题是否能得到解决,包括:

  • 缓存穿透
  • 指数据库没有数据,缓存中也没有数据,这样每次访问都会访问数据库,导致数据压力增大。

  • 缓存雪崩
  • 指缓存不可用或者缓存超时时间相同,在同一时间段内失效,大量请求访问数据库导致系统雪崩。

  • 缓存击穿
  • 指某个key设置了失效时间,其又是热点,如果该key失效,大量的请求过来,缓存未命中,则数据库访问量急剧增加。

  • 缓存污染
  • 缓存数据更新,而数据库数据未更新时,就造成了缓存污染。

    2.4. 开源框架

    缓存的开源框架很多,当时间和精力有限时,先集中精力研究几个主流的,以后有了时间或者要向缓存专家发展时,再去研究其他的。当下可以先熟悉如下几个:

  • JetCache
  • 理由前面已经提及。

  • Caffeine
  • 据说是在谷歌Guava Cache的基础上进行的优化;同时是Spring 5默认支持的Cache;Caffeine提出一种新的算法W-TinyLFU,它可以解决频率统计不准确以及访问频率衰减问题,命中率高。

  • Redis
  • 没啥好说的,在分布式缓存应用中使用很多。

    end.

    原文  https://juejin.im/post/5eb967376fb9a0435a01d8ee
    正文到此结束
    Loading...