本地缓存,这个实际在很多项目中用的蛮多,特别是单体架构的时候。数据量不大,并且没有分布式要求的话,使用本地缓存还是可以的。
常见的单体架构图如下,我们使用 Nginx 来做负载均衡,部署两个相同的服务到服务器,两个服务使用同一个数据库,并且使用的是本地缓存。
连个项目各自缓存,不共享
本地缓存的方案有哪些呢?
一:JDK 自带的 HashMap
和 ConcurrentHashMap
ConcurrentHashMap
可以看作是线程安全版本的 HashMap,
两者都是存放 key/value 形式的键值对。但是,大部分场景来说不会使用这两者当做缓存,因为只提供了缓存的功能,并没有提供其他诸如过期时间之类的功能。一个稍微完善一点的缓存框架至少要提供:过期时间、淘汰机制、命中率统计这三点。
二:Ehcache
、 Guava Cache
、Spring Cache
这三者是使用的比较多的本地缓存框架
Ehcache:
1.相较于更轻量(与其他两个对比)
2.可以嵌入到hibernate和mybatis作为多级缓存
3.可以将缓存数据持久化到磁盘
4.提供集群(可忽略,不好用)
Guava Cache
和Spring Cache
两者的话比较像
Guava:
1.相较于Spring Cache使用较多
2.提供了api,方便使用
3.设置了缓存有效时间
4.内部实现也比较干净,很多地方都和ConcurrentHashMap
的思想有异曲同工之妙
Spring Cache
的注解实现缓存的话,代码会看着很干净和优雅,但是很容易出现问题比如缓存穿透、内存溢出
三 :Caffeine
相比于 Guava
来说 Caffeine
在各个方面比如性能要更加优秀,一般建议使用其来替代 Guava,
并且, Guava
和 Caffeine
的使用方式很像!
本地缓存固然好,但是缺陷也很明显,比如多个相同服务之间的本地缓存的数据无法共享。
继而有了分布式缓存,首先让我们看看为什么用分布式缓存代替本地缓存:redis补充之为什么要有分布式缓存?/为什么不直接用本地缓存?
参考文档:
https://github.com/Snailclimb/JavaGuide/blob/master/docs/database/Redis/redis-all.md