每一级缓存的意义
时效性高的数据:采取DB和redis缓存双写方案
时效性不高的数据:采取nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构
a: nginx本地缓存,抗的是热数据的高并发访问。利用nginx本地缓存,将热数据锁定在nginx的本地缓存内,那么对这些热数据的大量访问,就直接走nginx就可以,不需要走后续的各种网络开销了。
b: redis分布式大规模缓存,抗的是很高的离散访问,支撑海量的数据,高并发的访问,高可用的服务。最完整的数据和缓存。
c: tomcat jvm堆内存缓存,主要是抗redis大规模灾难的,如果redis出现了大规模的宕机,导致nginx大量流量直接涌入数据生产服务,那么最后的tomcat堆内存缓存至少可以再抗一下,不至于让数据库直接裸奔, 同时tomcat jvm堆内存缓存,也可以抗住redis没有cache住的最后那少量的部分缓存。
Redis
Redis Cluster
通过master的水平扩容,来横向扩展读写吞吐量,还有支撑更多的海量数据
redis cluster 高可用性:redis cluster 提供主备切换。slave做master的热备,一旦master故障。slave提升为master,对外提供服务,保证集群的高可用性。并且,当master恢复后,会作为 slave加入到集群中。
redis cluster水平扩容
master的水平扩容,来横向扩展读写吞吐量,还有支撑更多的海量数据
slave 自动迁移
为redis cluster 添加冗余slave
redis性能(需根据机器配置测试)
redis单机,读吞吐是5w/s,写吞吐2w/s
扩展redis更多master,那么如果有5台master,不就读吞吐可以达到总量25w/s QPS,写可以达到10w/s QPS
redis单机,内存,6G-8G,内存不易过大fork类操作的时候很耗时,会导致请求延时的问题。扩容到5台master,能支撑的总的缓存数据量就是30G
Cache Aside模式
1 | (1)读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据后放入缓存,同时返回响应 |
DB和缓存双写不一致问题以及解决方案
缓存不一致场景一:
1 | 解决思路: |
缓存不一致场景二:
1 | 解决思路: |
大value缓存的全量更新效率低下问题
缓存数据的维度化拆分
缓存数据生产服务工作流程
(1)监听多个kafka topic,每个kafka topic对应一个服务(简化一下,监听一个kafka topic)
(2)如果一个服务发生了数据变更,那么就发送一个消息到kafka topic中
(3)缓存数据生产服务监听到了消息以后,就发送请求到对应的服务中调用接口以及拉取数据,此时是从mysql中查询的
(4)缓存数据生产服务拉取到了数据之后,会将数据在本地缓存中写入一份,就是ehcache中
同时会将数据在redis中写入一份
缓存并发重建冲突解决方案
重建缓存:比如数据在所有的缓存中都不存在了(LRU算法弄掉了),就需要重新查询数据写入缓存,重建缓存
1 | 缓存重建存在的问题一: |
1 | 缓存重建存在的问题二: |
缓存雪崩问题
1 | 缓存雪崩产生场景: |
缓存穿透问题
每次如果从生产查询到的数据是空,就说明这个数据根本就不存在
那么如果这个数据不存在的话,我们不要不往redis和ehcache等缓存中写入数据,我们呢,给写入一个空的数据,比如说空的productInfo的json串
因为我们有一个异步监听数据变更的机制在里面,也就是说,如果数据变更的话,某个数据本来是没有的,可能会导致缓存穿透,所以我们给了个空数据
但是现在这个数据有了,我们接收到这个变更的消息过后,就可以将数据再次从生产服务中查询出来
然后设置到各级缓存中去了
缓存失效问题
设置随机的缓存失效时间