• Redis + Caffeine = 王炸!!


    在高性能的服务架构设计中,缓存是一个不可或缺的环节。在实际的项目中,我们通常会将一些热点数据存储RedisMemCache这类缓存中间件中,只有当缓存的访问没有命中时再查询数据库。在提升访问速度的同时,也能降低数据库的压力。

    随着不断的发展,这一架构也产生了改进,在一些场景下可能单纯使用Redis类的远程缓存已经不够了,还需要进一步配合本地缓存使用,例如Guava cacheCaffeine,从而再次提升程序的响应速度与服务性能。于是,就产生了使用本地缓存作为一级缓存,再加上远程缓存作为二级缓存的两级缓存架构。

    在先不考虑并发等复杂问题的情况下,两级缓存的访问流程可以用下面这张图来表示:

    图片

    优点与问题

    那么,使用两级缓存相比单纯使用远程缓存,具有什么优势呢?

    • 本地缓存基于本地环境的内存,访问速度非常快,对于一些变更频率低、实时性要求低的数据,可以放在本地缓存中,提升访问速度

    • 使用本地缓存能够减少和Redis类的远程缓存间的数据交互,减少网络I/O开销,降低这一过程中在网络通信上的耗时

    但是在设计中,还是要考虑一些问题的,例如数据一致性问题。首先,两级缓存与数据库的数据要保持一致,一旦数据发生了修改,在修改数据库的同时,本地缓存、远程缓存应该同步更新。

    另外,如果是分布式环境下,一级缓存之间也会存在一致性问题,当一个节点下的本地缓存修改后,需要通知其他节点也刷新本地缓存中的数据,否则会出现读取到过期数据的情况,这一问题可以通过类似于Redis中的发布/订阅功能解决。

    此外,缓存的过期时间、过期策略以及多线程访问的问题也都需要考虑进去,不过我们今天暂时先不考虑这些问题,先看一下如何简单高效的在代码中实现两级缓存的管理。

    这或许是一个对你有用的开源项目,mall项目是一套基于 SpringBoot + Vue + uni-app 实现的电商系统(Github标星60K),采用Docker容器化部署,后端支持多模块和微服务架构。包括前台商城项目和后台管理系统,能支持完整的订单流程!涵盖商品、订单、购物车、权限、优惠券、会员、支付等功能!

    • Boot项目:https://github.com/macrozheng/mall

    • Cloud项目:https://github.com/macrozheng/mall-swarm

    • 视频教程:https://www.macrozheng.com/video/

    项目演示:

    图片

    准备工作

    在简单梳理了一下要面对的问题后,下面开始两级缓存的代码实战,我们整合号称最强本地缓存的Caffeine作为一级缓存、性能之王的Redis作为二级缓存。首先建一个springboot项目,引入缓存要用到的相关的依赖:

    1. <dependency>
    2.     <groupId>com.github.ben-manes.caffeine</groupId>
    3.     <artifactId>caffeine</artifactId>
    4.     <version>2.9.2</version>
    5. </dependency>
    6. <dependency>
    7.     <groupId>org.springframework.boot</groupId>
    8.     <artifactId>spring-boot-starter-data-redis</artifactId>
    9. </dependency>
    10. <dependency>
    11.     <groupId>org.springframework.boot</groupId>
    12.     <artifactId>spring-boot-starter-cache</artifactId>
    13. </dependency>
    14. <dependency>
    15.     <groupId>org.apache.commons</groupId>
    16.     <artifactId>commons-pool2</artifactId>
    17.     <version>2.8.1</version>
    18. </dependency>

    application.yml中配置Redis的连接信息:

    1. spring:
    2.   redis:
    3.     host: 127.0.0.1
    4.     port: 6379
    5.     database: 0
    6.     timeout: 10000ms
    7.     lettuce:
    8.       pool:
    9.         max-active: 8
    10.         max-wait: -1ms
    11.         max-idle: 8
    12.         min-idle: 0

    在下面的例子中,我们将使用RedisTemplate来对redis进行读写操作,RedisTemplate使用前需要配置一下ConnectionFactory和序列化方式,这一过程比较简单就不贴出代码了,有需要本文全部示例代码的可以在文末获取

    下面我们在单机环境下,将按照对业务侵入性的不同程度,分三个版本来实现两级缓存的使用。

    V1.0版本

    我们可以通过手动操作Caffeine中的Cache对象来缓存数据,它是一个类似Map的数据结构,以key作为索引,value存储数据。在使用Cache前,需要先配置一下相关参数:

    1. @Configuration
    2. public class CaffeineConfig {
    3.     @Bean
    4.     public Cache<String,ObjectcaffeineCache(){
    5.         r
  • 相关阅读:
    阿里巴巴中国站上传图片到1688 API 返回值说明
    python(进阶篇)——selenium自动化操作浏览器
    VR古迹复原——数字化复原圆明园,开创文化遗产保护新方式
    Python性能测试框架Locust实战教程
    使用 Qt for Android 获取并利用手机传感器数据(下篇)使用C++实现功能
    mongoDB如何根据条件分组汇总
    thingsboard3.4版本之OTA升级
    2023秋招--梦加网络--游戏客户端--二面面经
    成都理工大学_Python程序设计_第7章
    Windows/Linux(命令、安装包和源码安装)平台各个版本QT详细安装教程
  • 原文地址:https://blog.csdn.net/LINgZone2/article/details/136555674