本篇文章为你整理了用Java写一个分布式缓存——缓存管理(java分布式存储技术)的详细内容,包含有java 分布式存储 java分布式存储技术 jvm分布式缓存 java做缓存 用Java写一个分布式缓存——缓存管理,希望能帮助你了解 用Java写一个分布式缓存——缓存管理。
之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结
源码:https://github.com/weloe/Java-Distributed-Cache
之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结
源码:weloe/Java-Distributed-Cache (github.com)
本篇代码:
Java-Distributed-Cache/src/main/java/com/weloe/cache/cachemanager at master · weloe/Java-Distributed-Cache (github.com)
Java-Distributed-Cache/src/test/java/com/weloe/cache/cachemanager at master · weloe/Java-Distributed-Cache (github.com)
上篇:
https:///weloe/p/17050512.html
既然是分布式缓存,那么就一定会有缓存管理方面的问题,既然是要储存的数据,那么就不能让它无限制的存储,就需要设置临界值,这个也是需要缓存淘汰的原因。
而为了对缓存方便管理,比如,我们需要缓存的有多个功能,我们为了方便区分,可能就需要在key前加上功能前缀,这样不仅变得麻烦,同时由于key变大,也会增加内存的压力。
所以我们就需要把缓存分组进行管理,并提供一些方便的对外接口
CacheObj
Java-Distributed-Cache/CacheObj.java at master · weloe/Java-Distributed-Cache (github.com)
在前篇缓存淘汰中,我们确定了我们真正存储数据的是一个k,v结构,因此,我们需要抽象出这里的k,v,k选择String,而v则抽象出一个CacheObj。
需要注意的是,这里的endTime是该缓存到期的时间,一般而言,我们都有为目标缓存设定缓存时间的需求,这也是缓存淘汰策略中的一种。实际存储为byte[]则是为了通用性。
public class CacheObj {
private LocalDateTime endTime;
private Class clazz;
private int byteSize;
// 存储的实际数据
private byte[] data;
public CacheObj() {
public CacheObj(LocalDateTime endTime,Class clazz ,int byteSize, byte[] data) {
this.endTime = endTime;
this.clazz = clazz;
this.byteSize = byteSize;
this.data = data;
public int getByteSize() {
return byteSize;
public byte[] getData() {
return data;
Cache
Java-Distributed-Cache/Cache.java at master · weloe/Java-Distributed-Cache (github.com)
有组管理,也就需要单一的缓存管理
public class Cache {
// 最大字节
private int maxByteSize;
// 目前使用字节
private int normalByteSize;
// 缓存策略
private CacheStrategy String, CacheObj cacheStrategy;
Lock readLock;
Lock writeLock;
public Cache(int maxByteSize, CacheStrategy String, CacheObj cacheStrategy) {
this.maxByteSize = maxByteSize;
this.normalByteSize = 0;
this.cacheStrategy = cacheStrategy;
readLock = new ReentrantReadWriteLock().readLock();
writeLock = new ReentrantReadWriteLock().writeLock();
public CacheObj add(String key, CacheObj cacheObj) {
writeLock.lock();
normalByteSize += cacheObj.getByteSize();
// 缓存上限
while (normalByteSize maxByteSize) {
// 淘汰缓存
CacheObj outCache = cacheStrategy.outCache();
normalByteSize -= outCache.getByteSize();
// 加入缓存
CacheObj v = cacheStrategy.put(key, cacheObj);
writeLock.unlock();
return v;
public CacheObj get(String key) {
readLock.lock();
CacheObj v = cacheStrategy.get(key);
// 判断是否过期
if (v != null v.getEndTime() != null LocalDateTime.now().isAfter(v.getEndTime())) {
CacheObj obj = cacheStrategy.outCache(key);
return null;
readLock.unlock();
return v;
public CacheObj remove(String key){
return cacheStrategy.outCache(key);
public void clear(){
cacheStrategy.clear();
public void setMaxByteSize(int maxByteSize) {
this.maxByteSize = maxByteSize;
public int getMaxByteSize() {
return maxByteSize;
public int getNormalByteSize() {
return normalByteSize;
Group
Java-Distributed-Cache/Group.java at master · weloe/Java-Distributed-Cache (github.com)
既然需要组管理,那么就需要抽象出一个Group类型,这里的getter是需要后期自定义的回调函数。
public class Group {
private String name;
private Cache cache;
private Getter getter;
@FunctionalInterface
interface Getter {
byte[] get(String k) throws Exception;
put,get
为了方便管理,Group需要提供get,put法
public CacheObj get(String key) {
if ("".equals(key) key == null) {
throw new RuntimeException("key不能为空");
CacheObj cacheObj = cache.get(key);
if (cacheObj != null) {
return cacheObj;
return load(key);
* 通过Getter回调获取数据
* @param key
* @return
private CacheObj load(String key) {
byte[] bytes = null;
try {
bytes = getter.get(key);
} catch (Exception e) {
e.printStackTrace();
return null;
if (bytes == null) {
return null;
CacheObj cacheObj = BytesUtil.bytes2CacheObj(bytes);
cache.add(key, cacheObj);
return cacheObj;
public CacheObj putCacheObj(String key,CacheObj cacheObj){
CacheObj obj = cache.add(key, cacheObj);
return obj;
expire
为存储的数据设定存储时间的方法
public CacheObj expire(String key, long num, ChronoUnit timeUnit){
CacheObj cacheObj;
try {
cacheObj = cache.get(key);
cacheObj.setEndTime(LocalDateTime.now().plus(num, timeUnit));
} catch (Exception e) {
return null;
return cacheObj;
setSize
设置缓存临界值的方法
public boolean setMaxSize(int num){
if(num cache.getNormalByteSize()){
return false;
cache.setMaxByteSize(num);
return true;
delete,clear
清除组缓存的方法,从这里也可以看出其方便性,即可以清除单一功能(组)的缓存
public CacheObj delete(String key){
CacheObj obj = cache.remove(key);
return obj;
public void clear(){
cache.clear();
GroupManager
Java-Distributed-Cache/GroupManager.java at master · weloe/Java-Distributed-Cache (github.com)
既然有Group,就需要管理Group,也就需要相对应的put,get方法
public class GroupManager {
private Map String, Group groupMap;
CacheTest
Java-Distributed-Cache/CacheTest.java at master · weloe/Java-Distributed-Cache (github.com)
class CacheTest {
Cache cache;
@BeforeEach
void setUp() {
CacheStrategy String, CacheObj lruCache = new LRUCache (5);
lruCache.setCallback((s1, s2)- System.out.println("缓存淘汰"));
cache = new Cache(1024*1024,lruCache);
@Test
void add() {
String s = "123";
CacheObj cacheObj = new CacheObj(LocalDateTime.MAX, String.class, 512*1024, s.getBytes(StandardCharsets.UTF_8));
cache.add("test", cacheObj);
for (int i = 0; i i++) {
cache.add("test"+i,cacheObj);
@Test
void get() {
CacheObj cacheObj = cache.get("123");
Assertions.assertNull(cacheObj);
String s = "123";
cacheObj = new CacheObj(LocalDateTime.MAX,String.class, s.getBytes(StandardCharsets.UTF_8).length, s.getBytes(StandardCharsets.UTF_8));
cache.add("test", cacheObj);
CacheObj test = cache.get("test");
Assertions.assertNotNull(test);
byte[] data = test.getData();
String s1 = BytesUtil.bytes2String(data);
System.out.println(s1);
GroupTest
Java-Distributed-Cache/GroupTest.java at master · weloe/Java-Distributed-Cache (github.com)
package com.weloe.cache.cachemanager;
import com.weloe.cache.outstrategy.CacheStrategy;
import com.weloe.cache.outstrategy.LRUCache;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
class GroupTest {
Group group;
@BeforeEach
void setUp() {
CacheStrategy String, CacheObj lruCache = new LRUCache (5);
lruCache.setCallback((s1, s2)- System.out.println("缓存淘汰"));
group = new Group("group1", new Cache(1024*1024,lruCache), str - {
System.out.println("group1回调");
return new byte[0];
String x = "132";
group.putCacheObj("cache1",new CacheObj(null,String.class,x.getBytes(StandardCharsets.UTF_8).length,x.getBytes(StandardCharsets.UTF_8)));
@Test
void expire() {
String x = "132";
group.putCacheObj("cache1",new CacheObj(null,String.class,x.getBytes(StandardCharsets.UTF_8).length,x.getBytes(StandardCharsets.UTF_8)));
CacheObj cache1 = group.expire("cache1", 2, ChronoUnit.MINUTES);
System.out.println(cache1.getEndTime());
System.out.println(group.get("cache1").getEndTime());
Assertions.assertSame(cache1.getEndTime(),group.get("cache1").getEndTime());
GroupManagerTest
Java-Distributed-Cache/GroupManagerTest.java at master · weloe/Java-Distributed-Cache (github.com)
package com.weloe.cache.cachemanager;
import com.weloe.cache.outstrategy.LRUCache;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;
class GroupManagerTest {
GroupManager groupManager;
@BeforeEach
void setUp() {
Group group1 = new Group("group1",
new Cache(1024*1024, new LRUCache (5,(s1, s2)- System.out.println("group1缓存淘汰"))),
str - {System.out.println("group1未获取缓存的回调");return new byte[0];}
Group group2 = new Group("group2",
new Cache(1024*1024, new LRUCache (5,(s1, s2)- System.out.println("group2缓存淘汰"))),
str - {System.out.println("group2未获取缓存的回调");return new byte[0];}
groupManager = new GroupManager(new HashMap (),new ReentrantLock());
groupManager.put(group1);
groupManager.put(group2);
System.out.println(groupManager.getGroup(""));
System.out.println(groupManager.getGroup("group1"));
System.out.println(groupManager.getGroup("group2").getName());
@Test
void put() {
Group group3 = new Group("group3",
new Cache(1024*1024, new LRUCache (5,(s1, s2)- System.out.println("group3缓存淘汰"))),
str - {System.out.println("group3未获取缓存的回调");return new byte[0];}
groupManager.put(group3);
System.out.println(groupManager.getGroup("group3").getName());
以上就是用Java写一个分布式缓存——缓存管理(java分布式存储技术)的详细内容,想要了解更多 用Java写一个分布式缓存——缓存管理的内容,请持续关注盛行IT软件开发工作室。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。