概述

缓存框架我们有ehcache 和 redis 分别是 本地内存缓存和 分布式缓存框架。在实际情况下如果单台机器 使用ehcache 就可以满足需求了,速度快效率高,有些数据如果需要多台机器共享这个时候怎么办呢,我们需要通过redis,将缓存存放到redis上面。

这也会导致一个问题,因为所有的请求都会到redis读取,当大量的读取会导致大量的网络流量,因此网络流量会成为访问的瓶颈。

J2CACHE就是解决这个问题而生的,缓存分为两级

L1: 进程内缓存(caffeine\ehcache)

L2: Redis/Memcached 集中式缓存

数据读取流程

读取顺序 -> L1 -> L2

缓存先读取L1 ,不存在则读取L2

数据更新

1 从数据库中读取最新数据,依次更新 L1 -> L2 ,发送广播清除某个缓存信息
2 接收到广播(手工清除缓存 & 一级缓存自动失效),从 L1 中清除指定的缓存信息

测试J2CACHE

创建一个maven 项目

引入

  1. <dependency><!-- Ehcache 3.x //-->
  2. <groupId>org.ehcache</groupId>
  3. <artifactId>ehcache</artifactId>
  4. <version>3.4.0</version>
  5. </dependency>
  6.  
  7. <dependency>
  8. <groupId>net.oschina.j2cache</groupId>
  9. <artifactId>j2cache-core</artifactId>
  10. <version>2.7.7-release</version>
  11. </dependency>

引入配置文件

ehcache3.xml

j2cache.properties

这个配置文件配置如下:

  1. #J2Cache configuration
  2.  
  3. #########################################
  4. # Cache Broadcast Method
  5. # values:
  6. # jgroups -> use jgroups's multicast
  7. # redis -> use redis publish/subscribe mechanism (using jedis)
  8. # lettuce -> use redis publish/subscribe mechanism (using lettuce, Recommend)
  9. # rabbitmq -> use RabbitMQ publisher/consumer mechanism
  10. # rocketmq -> use RocketMQ publisher/consumer mechanism
  11. # none -> don't notify the other nodes in cluster
  12. # xx.xxxx.xxxx.Xxxxx your own cache broadcast policy classname that implement net.oschina.j2cache.cluster.ClusterPolicy
  13. #########################################
  14.  
  15. j2cache.broadcast = redis
  16.  
  17. #########################################
  18. # Level 1&2 provider
  19. # values:
  20. # none -> disable this level cache
  21. # ehcache -> use ehcache2 as level 1 cache
  22. # ehcache3 -> use ehcache3 as level 1 cache
  23. # caffeine -> use caffeine as level 1 cache(only in memory)
  24. # redis -> use redis as level 2 cache (using jedis)
  25. # lettuce -> use redis as level 2 cache (using lettuce)
  26. # readonly-redis -> use redis as level 2 cache ,but never write data to it. if use this provider, you must uncomment `j2cache.L2.config_section` to make the redis configurations available.
  27. # memcached -> use memcached as level 2 cache (xmemcached),
  28. # [classname] -> use custom provider
  29. #########################################
  30.  
  31. j2cache.L1.provider_class = ehcache3
  32. j2cache.L2.provider_class = redis
  33.  
  34. # When L2 provider isn't `redis`, using `L2.config_section = redis` to read redis configurations
  35. # j2cache.L2.config_section = redis
  36.  
  37. # Enable/Disable ttl in redis cache data (if disabled, the object in redis will never expire, default:true)
  38. # NOTICE: redis hash mode (redis.storage = hash) do not support this feature)
  39. j2cache.sync_ttl_to_redis = true
  40.  
  41. # Whether to cache null objects by default (default false)
  42. j2cache.default_cache_null_object = true
  43.  
  44. #########################################
  45. # Cache Serialization Provider
  46. # values:
  47. # fst -> using fast-serialization (recommend)
  48. # kyro -> using kyro serialization
  49. # json -> using fst's json serialization (testing)
  50. # fastjson -> using fastjson serialization (embed non-static class not support)
  51. # java -> java standard
  52. # [classname implements Serializer]
  53. #########################################
  54.  
  55. j2cache.serialization = fst
  56. #json.map.person = net.oschina.j2cache.demo.Person
  57.  
  58. #########################################
  59. # Ehcache configuration
  60. #########################################
  61.  
  62. # ehcache.configXml = /ehcache.xml
  63.  
  64. # ehcache3.configXml = /ehcache3.xml
  65. # ehcache3.defaultHeapSize = 1000
  66.  
  67. #########################################
  68. # Redis connection configuration
  69. #########################################
  70.  
  71. #########################################
  72. # Redis Cluster Mode
  73. #
  74. # single -> single redis server
  75. # sentinel -> master-slaves servers
  76. # cluster -> cluster servers (\u93c1\u7248\u5d41\u6434\u64bb\u53a4\u7f03\ue1bd\u68e4\u93c1\u582c\u7d1d\u6d63\u8de8\u6564 database = 0\u951b\ufffd
  77. # sharded -> sharded servers (\u7035\u55d9\u721c\u9286\u4f79\u669f\u93b9\ue1bc\u7c31\u8e47\u5474\u300f\u9366\ufffd hosts \u6d93\ue15f\u5bda\u7039\u6c3e\u7d1d\u6d93\u65c7\u7e5b\u93ba\u30e6\u775c\u95b0\u5d87\u7586\u93c3\u72b3\u6665 ; redis://user:password@127.0.0.1:6379/0\u951b\ufffd
  78. #
  79. #########################################
  80.  
  81. redis.mode = sentinel
  82.  
  83. #redis storage mode (generic|hash)
  84. redis.storage = generic
  85.  
  86. ## redis pub/sub channel name
  87. redis.channel = j2cache
  88. ## redis pub/sub server (using redis.hosts when empty)
  89. redis.channel.host =
  90.  
  91. #cluster name just for sharded
  92. redis.cluster_name = mymaster
  93.  
  94. ## redis cache namespace optional, default[empty]
  95. redis.namespace =
  96.  
  97. ## connection
  98. # Separate multiple redis nodes with commas, such as 192.168.0.10:6379,192.168.0.11:6379,192.168.0.12:6379
  99.  
  100. redis.hosts = 202.10.79.170:16001,202.10.79.170:16002,202.10.79.170:16003
  101. redis.timeout = 10000
  102. redis.password =
  103. redis.database = 0
  104.  
  105. ## redis pool properties
  106. redis.maxTotal = 100
  107. redis.maxIdle = 10
  108. redis.maxWaitMillis = 5000
  109. redis.minEvictableIdleTimeMillis = 60000
  110. redis.minIdle = 1
  111. redis.numTestsPerEvictionRun = 10
  112. redis.lifo = false
  113. redis.softMinEvictableIdleTimeMillis = 10
  114. redis.testOnBorrow = true
  115. redis.testOnReturn = false
  116. redis.testWhileIdle = true
  117. redis.timeBetweenEvictionRunsMillis = 300000
  118. redis.blockWhenExhausted = false
  119. redis.jmxEnabled = false

广播方式使用redis

  1. j2cache.broadcast = redis
    L1,L2 缓存实现方法
  1. j2cache.L1.provider_class = ehcache3
  2. j2cache.L2.provider_class = redis
    redis 使用哨兵模式进行配置。
  3.  

使用代码进行测试

编写测试代码如下:

读取缓存

  1. public static void main(String[] args) throws InterruptedException {
  2.  
  3. CacheChannel cache = J2Cache.getChannel();
  4. while(true){
  5. System.out.println(cache.get("user", "name"));
  6. Thread.sleep(2000);
  7. }
  8. }

这个代码会一直读取 user:name 的缓存。

我们需要测试的是,当一个客户端设置一个 user:name 的缓存时,这个代码能反映缓存的变化。

设置缓存:

  1. public static void main(String[] args) {
  2.  
  3. CacheChannel cache = J2Cache.getChannel();
  4. cache.set("user", "name", "A");
  5. cache.close();
  6. }

首先设置一个A的缓存。

我们可以看到第一个代码返回的是如下情况

[user,name,L2]=>A
[user,name,L1]=>A
[user,name,L1]=>A

它会先从 redis读取,在读取本地。

我们在设置一次:

  1. public static void main(String[] args) {
  2.  
  3. CacheChannel cache = J2Cache.getChannel();
  4. cache.set("user", "name", "B");
  5. cache.close();
  6. }

第二次我们这个name 为 B,这个时候我们可以发现:

[user,name,L2]=>B
[user,name,L1]=>B
[user,name,L1]=>B

缓存变成了B ,而且是先读取 REDIS ,在读取 EHCACHE缓存,即先读取 L2 再读取L1。

这样我们的缓存就既能保证性能,有可以保证缓存及时被更新。

J2CACHE 两级缓存框架的更多相关文章

  1. Spring+ehcache+redis两级缓存

    问题描述 场景:我们的应用系统是分布式集群的,可横向扩展的.应用中某个接口操作满足以下一个或多个条件: 1. 接口运行复杂代价大, 2. 接口返回数据量大, 3. 接口的数据基本不会更改, 4. 接口 ...

  2. 用guava快速打造两级缓存能力

    首先,咱们都有一共识,即可以使用缓存来提升系统的访问速度! 现如今,分布式缓存这么强大,所以,大部分时候,我们可能都不会去关注本地缓存了! 而在一起高并发的场景,如果我们一味使用nosql式的缓存,如 ...

  3. Redis+Caffeine两级缓存,让访问速度纵享丝滑

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 在高性能的服务架构设计中,缓存是一个不可或缺的环节.在实际的项目中,我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中, ...

  4. 基于Spring接口,集成Caffeine+Redis两级缓存

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 在上一篇文章Redis+Caffeine两级缓存,让访问速度纵享丝滑中,我们介绍了3种整合Caffeine和Redis作为两级缓存使用的方法,虽 ...

  5. J2Cache 和普通缓存框架有何不同,它解决了什么问题?

    不少人看到 J2Cache 第一眼时,会认为这就是一个普普通通的缓存框架,和例如 Ehcache.Caffeine .Spring Cache 之类的项目没什么区别,无非是造了一个新的轮子而已.事实上 ...

  6. springboot中使用自定义两级缓存

    工作中用到了springboot的缓存,使用起来挺方便的,直接引入redis或者ehcache这些缓存依赖包和相关缓存的starter依赖包,然后在启动类中加入@EnableCaching注解,然后在 ...

  7. mybatis两级缓存原理剖析

    https://blog.csdn.net/zhurhyme/article/details/81064108 对于mybatis的缓存认识一直有一个误区,所以今天写一篇文章帮自己订正一下.mybat ...

  8. 阿里开源的缓存框架JetCache

    之前一直在用Spring Cache进行接口数据的缓存,主要是Spring Cache在对具体key缓存失效时间的设置不是很方法,还要自己去扩展,无意中发现了阿里的JetCache.大部分的需求都能满 ...

  9. 数据库历险记(三) | 缓存框架的连环炮 数据库历险记(二) | Redis 和 Mecached 到底哪个好? 数据库历险记(一) | MySQL这么好,为什么还有人用Oracle? 面对海量请求,缓存设计还应该考虑哪些问题?

    数据库历险记(三) | 缓存框架的连环炮   文章首发于微信公众号「陈树义」,专注于 Java 技术分享的社区.点击链接扫描二维码,与500位小伙伴一起共同进步.微信公众号二维码 http://p3n ...

随机推荐

  1. 铁板纹理 铁锈Rust

    软件:Substance Designer 2017.1.2 这篇文章记录铁锈的制作方法,铁锈效果见图一 图一:铁锈Rust 铁锈的具体制作过程为: 使用BnW Spots 2(Noise)结点生成噪 ...

  2. udev example -- detect usb and write test file

    之前学习了下Udev,就随便做了个测试小程序.....设计什么的也没考虑,就实现了一个基本功能,插入U盘,识别,循环检测到有特定文件后,就然后往U盘里面写数据,插拔多次,都能正常工作. 里面的warn ...

  3. 实验四:xl命令的常见子命令以及操作

    实验名称: xl命令的常见子命令以及操作 实验环境: 这里我们需要正常安装一台虚拟机,如下图: 我们这里以一台busybox为例,来进行这些简单的常见的操作: 实验要求: 这里我们准备了5个常见操作: ...

  4. syslog-ng日志收集分析服务搭建及配置

    syslog-ng日志收集分析服务搭建及配置:1.网上下载eventlog_0.2.12.tar.gz.libol-0.3.18.tar.gz.syslog-ng_3.3.5.tar.gz三个软件: ...

  5. Android 开发 框架系列 百度语音合成

    官方文档:http://ai.baidu.com/docs#/TTS-Android-SDK/6d5d6899 官方百度语音合成控制台:https://cloud.baidu.com/product/ ...

  6. QTP 学习 - 参数化

  7. 面试回顾——kafka

    关于消息队列的使用场景:https://www.cnblogs.com/linjiqin/p/5720865.html kafka: Topic Kafka将消息种子(Feed)分门别类 每一类的消息 ...

  8. jquery.cookie用法及其注意点

    jquery.cookie是一个轻量级的cookie插件,由于已被封装好,可拿来即用. 基本的创建.读取.删除见另一篇文章 浅谈localStorage.sessionStorage 与cookie  ...

  9. Android Room 学习(一)

    Room简介 Room persistence库为SQLite提供了一个抽象层,以便在利用SQLite的全部功能的同时实现更强大的数据库访问. 该库可帮助您在运行应用程序的设备上创建应用程序数据的缓存 ...

  10. logback的使用和logback.xml详解,在Spring项目中使用log打印日志

    logback的使用和logback.xml详解 一.logback的介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch.它当前分 ...