├── README.md
└── redis-caffeine-cache-starter
├── .gitignore
├── pom.xml
└── src
└── main
├── java
└── com
│ └── axin
│ └── idea
│ └── rediscaffeinecachestarter
│ ├── CacheRedisCaffeineAutoConfiguration.java
│ ├── CacheRedisCaffeineProperties.java
│ └── support
│ ├── CacheMessage.java
│ ├── CacheMessageListener.java
│ ├── CacheNames.java
│ ├── RedisCaffeineCache.java
│ └── RedisCaffeineCacheManager.java
└── resources
├── META-INF
└── spring.factories
└── demo.yml
/README.md:
--------------------------------------------------------------------------------
1 | # 分布式二级缓存
2 |
3 | 在生产中已有实践,本组件仅做个人学习交流分享使用。
4 |
5 | ## 所谓二级缓存
6 | > 缓存就是将数据从读取较慢的介质上读取出来放到读取较快的介质上,如磁盘-->内存。
7 |
8 | 平时我们会将数据存储到磁盘上,如:数据库。如果每次都从数据库里去读取,会因为磁盘本身的IO影响读取速度,所以就有了像redis这种的内存缓存。可以将数据读取出来放到内存里,这样当需要获取数据时,就能够直接从内存中拿到数据返回,能够很大程度的提高速度。
9 |
10 | 但是一般redis是单独部署成集群,所以会有网络IO上的消耗,虽然与redis集群的链接已经有连接池这种工具,但是数据传输上也还是会有一定消耗。所以就有了进程内缓存,如:caffeine。当应用内缓存有符合条件的数据时,就可以直接使用,而不用通过网络到redis中去获取,这样就形成了两级缓存。应用内缓存叫做一级缓存,远程缓存(如redis)叫做二级缓存。
11 |
12 | ## 系统是否需要缓存
13 |
14 | - **CPU占用**:如果你有某些应用需要消耗大量的cpu去计算获得结果。
15 | - **数据库IO占用**:如果你发现你的数据库连接池比较空闲,那么不应该用缓存。但是如果数据库连接池比较繁忙,甚至经常报出连接不够的报警,那么是时候应该考虑缓存了。
16 |
17 | ## 分布式二级缓存的优势
18 |
19 | Redis用来存储热点数据,Redis中没有的数据则直接去数据库访问。
20 |
21 | 已经有Redis了,干嘛还需要了解Guava,Caffeine这些进程缓存呢:
22 |
23 | - Redis如果不可用,这个时候我们只能访问数据库,很容易造成雪崩,但一般不会出现这种情况。
24 | - 访问Redis会有一定的网络I/O以及序列化反序列化开销,虽然性能很高但是其终究没有本地方法快,可以将最热的数据存放在本地,以便进一步加快访问速度。这个思路并不是我们做互联网架构独有的,在计算机系统中使用L1,L2,L3多级缓存,用来减少对内存的直接访问,从而加快访问速度。
25 |
26 | 所以如果仅仅是使用Redis,能满足我们大部分需求,但是当需要追求更高的性能以及更高的可用性的时候,那就不得不了解多级缓存。
27 |
28 | ## 二级缓存操作过程
29 |
30 | 数据读流程 | 描述
31 | ---|---
32 | | redis 与本地缓存都查询不到值的时候,会触发更新过程,整个过程是加锁的
33 |
34 |
35 | 缓存失效流程 | 描述
36 | ---|---
37 | | redis更新与删除缓存key都会触发,清除redis缓存后
38 |
39 |
40 | ## 如何使用组件?
41 |
42 | 组件是基于Spring Cache框架上改造的,在项目中使用分布式缓存,仅仅需要在缓存注解上增加:cacheManager ="L2_CacheManager",或者 cacheManager = CacheRedisCaffeineAutoConfiguration.分布式二级缓存
43 |
44 |
45 | ```Java
46 | //这个方法会使用分布式二级缓存来提供查询
47 | @Cacheable(cacheNames = CacheNames.CACHE_12HOUR, cacheManager = "L2_CacheManager")
48 | public Config getAllValidateConfig() {
49 | }
50 | ```
51 |
52 | 如果你想既使用分布式缓存,又想用分布式二级缓存组件,那你需要向Spring注入一个 @Primary 的 CacheManager bean 然后:
53 |
54 | ```Java
55 | //这个方法会使用分布式二级缓存
56 | @Cacheable(cacheNames = CacheNames.CACHE_12HOUR, cacheManager = "L2_CacheManager")
57 | public Config getAllValidateConfig() {
58 | }
59 |
60 | //这个方法会使用分布式缓存
61 | @Cacheable(cacheNames = CacheNames.CACHE_12HOUR)
62 | public Config getAllValidateConfig2() {
63 | }
64 | ```
65 |
66 |
--------------------------------------------------------------------------------
/redis-caffeine-cache-starter/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/redis-caffeine-cache-starter/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.1.9.RELEASE
9 |
10 |
11 |
12 | com.axin.idea
13 | redis-caffeine-cache-starter
14 | 1.0.0-SNAPSHOT
15 |
16 | redis-caffeine-cache-starter
17 | 分布式二级缓存装载组件
18 |
19 |
20 |
21 | 2.8.0
22 | 1.2.70
23 | 1.16.20
24 |
25 |
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-data-redis
31 | provided
32 |
33 |
34 |
35 | org.projectlombok
36 | lombok
37 | ${lombok.version}
38 |
39 |
40 |
41 | com.github.ben-manes.caffeine
42 | caffeine
43 | ${caffeine.version}
44 |
45 |
46 |
47 | com.alibaba
48 | fastjson
49 | ${fastjson.version}
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/redis-caffeine-cache-starter/src/main/java/com/axin/idea/rediscaffeinecachestarter/CacheRedisCaffeineAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.axin.idea.rediscaffeinecachestarter;
2 |
3 | import com.axin.idea.rediscaffeinecachestarter.support.CacheMessageListener;
4 | import com.axin.idea.rediscaffeinecachestarter.support.RedisCaffeineCacheManager;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
9 | import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
10 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 | import org.springframework.data.redis.core.RedisTemplate;
14 | import org.springframework.data.redis.listener.ChannelTopic;
15 | import org.springframework.data.redis.listener.RedisMessageListenerContainer;
16 |
17 |
18 | @Configuration
19 | @AutoConfigureAfter(RedisAutoConfiguration.class)
20 | @EnableConfigurationProperties(CacheRedisCaffeineProperties.class)
21 | @Slf4j
22 | public class CacheRedisCaffeineAutoConfiguration {
23 |
24 | @Autowired
25 | private CacheRedisCaffeineProperties cacheRedisCaffeineProperties;
26 |
27 | @Bean("L2_CacheManager")
28 | @ConditionalOnBean(RedisTemplate.class)
29 | public RedisCaffeineCacheManager cacheManager(RedisTemplate