J2Cache 是 OSChina 目前正在使用的两级缓存框架。第一级缓存使用 Ehcache,第二级缓存使用 Redis。由于大量的缓存读取会导致 L2 的网络成为整个系统的瓶颈,因此 L1 的目标是降低对 L2 的读取次数。该缓存框架主要用于集群环境中。单机也可使用,用于避免应用重启导致的 Ehcache 缓存数据丢失。
J2Cache 从 1.3.0 版本开始支持 JGroups 和 Redis Pub/Sub 两种方式进行缓存事件的通知。在某些云平台上可能无法使用 JGroups 组播方式,可以采用 Redis 发布订阅的方式。
J2Cache 的两级缓存结构
L1:进程内缓存(caffeine / ehcache)
L2:Redis / Memcached 集中式缓存
不少人看到 J2Cache 第一眼时,会认为这就是一个普普通通的缓存框架,和例如 Ehcache、Caffeine 、Spring Cache 之类的项目没什么区别,无非是造了一个新的轮子而已。事实上完全不是一回事!
目前缓存的解决方案一般有两种:
内存缓存(如 Ehcache)—— 速度快,进程内可用
集中式缓存(如 Redis)—— 可同时为多节点提供服务
现有的缓存框架已经非常成熟而且优秀,J2Cache 无心造一个新的轮子,它要解决的几个问题如下:
使用内存缓存时,一旦应用重启后,由于缓存数据丢失,缓存雪崩,给数据库造成巨大压力,导致应用堵塞;
使用内存缓存时,多个应用节点无法共享缓存数据;
使用集中式缓存,由于大量的数据通过缓存获取,导致缓存服务的数据吞吐量太大,带宽跑满。现象就是 Redis 服务负载不高,但是由于机器网卡带宽跑满,导致数据读取非常慢;
在遭遇问题1、2 时,很多人自然而然会想到使用 Redis 来缓存数据,因此就难以避免的导致了问题 3 的发生。
当发生问题 3 时,又有很多人想到 Redis 的集群,通过集群来降低缓存服务的压力,特别是带宽压力。
但其实,这个时候的 Redis 上的数据量并不一定大,仅仅是数据的吞吐量大而已。
(1)从数据库中读取最新数据,依次更新 L1(一级缓存) -> L2(二级缓存) ,发送广播清除某个缓存信息;
(2)接收到广播(手工清除缓存 & 一级缓存自动失效),从 L1 中清除指定的缓存信息;
配置文件位于 core/resources 目录下,如下图:
其中,j2cache.properties 文件是必须的,这是主配置文件。其他则根据你选择的组件可选添加,它们的含义分别如下:
j2cache.properties:J2Cache 核心配置文件,可配置两级的缓存,Redis 服务器、连接池以及缓存广播的方式
caffeine.properties:如果一级缓存选用 Caffeine ,那么该文件用来配置缓存信息
ehcache.xml:Ehcache 的配置文件,配置说明请参考 Ehcache 文档
ehcache3.xml:Ehcache3 的配置文件,配置说明请参考 Ehcache 文档
network.xml:JGroups 网络配置,如果使用 JGroups 组播的话需要这个文件,一般无需修改
实际使用过程需要将所需的配置文件复制到应用类路径中,如 WEB-INF/classes 目录。