实现concurrentHashMap与redis两级缓存
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class TwoLevelCacheService {
private ConcurrentHashMap<String, Object> localCache = new ConcurrentHashMap<>();
private static final String REDIS_CACHE_PREFIX = "mycache:";
@Autowired
private Jedis jedis;
@Cacheable(value = "mycache", key = "#key")
public Object getData(String key) {
if (localCache.containsKey(key)) {
return localCache.get(key);
} else {
Object data = jedis.get(REDIS_CACHE_PREFIX + key);
if (data != null) {
localCache.put(key, data);
}
return data;
}
}
@CacheEvict(value = "mycache", key = "#key")
public void clearCache(String key) {
localCache.remove(key);
jedis.del(REDIS_CACHE_PREFIX + key);
}
// Example method for adding/updating data in cache
public void putData(String key, Object data) {
localCache.put(key, data);
jedis.set(REDIS_CACHE_PREFIX + key, data.toString());
}
}
localCache是一个ConcurrentHashMap用于实现内存级别的缓存,而jedis对象是通过Spring的依赖注入来获取的用于操作Redis。
getData方法首先在本地缓存(localCache)中查找数据,如果数据不存在,则从Redis中获取,并将其存储到本地缓存以供下次使用。
clearCache方法用于除本地缓存和Redis中的缓存数据。
putData`方法示范了如何将数据添加其中数据会被存储在本地缓存和Redis中。
请注意,以上示例仅为演示目的,并可能需要根据实际需求进行适当的修改和调整。另外,确保已正确配置和初始化Redis连接,以及已启用Spring的缓存功能。
在分布式架构中,使用ConcurrentHashMap和Redis实现两级缓存需要考虑多个节点之间的数据一致性和并发访问问题。以下是一种基于分布式锁实现的示例代码:
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
@Service
public class DistributedCacheService {
private ConcurrentHashMap<String, Object> localCache = new ConcurrentHashMap<>();
@Autowired
private RedissonClient redissonClient;
public Object getData(String key) {
if (localCache.containsKey(key)) {
return localCache.get(key);
} else {
Lock lock = redissonClient.get(key);
lock.lock();
try {
// Double-checked locking to prevent multiple threads refreshing the cache simultaneously
if (localCache.containsKey(key)) {
return localCache.get(key);
} else {
// Get data from Redis
RBucket<Object> bucket = redissonClient.getBucket(key);
Object data = bucket.get();
if (data != null) {
localCache.put(key, data);
}
return data;
}
} finally {
lock.unlock();
}
}
}
public void putData(String key, Object data) {
RBucket<Object> bucket = redissonClient.getBucket(key);
bucket.set(data);
localCache.put(key, data);
}
public void evictData(String key) {
RBucket<Object> bucket = redissonClient.getBucket(key);
bucket.delete();
localCache.remove(key);
}
}
在getData方法中,首先在本地缓存(localCache)中检查数据,如果数据不存在,则获取一个Redisson分布式锁并进行加锁操作。进入加锁代码块后,再次检查本地缓存是否有数据,以防止其他线程在等待锁的过程中已经加载了数据。如果本地缓存依然没有数据,则从Redis中获取数据,并将其存储到本地缓存中。最后,在退出加锁代码块之前释放分布式锁。
putData方法用于存储数据,通过Redisson的RBucket对象将数据存储到Redis中,并同时更新本地缓存。
evictData方法用于清除数据,删除Redis中对应的数据并从本地缓存中移除。
请注意,上述示例中的分布式锁实现是基于Redisson的Redis分布式锁,你也可以选择其他基于Redis的分布式锁实现方式。此外,确保已正确配置和初始化Redis连接和Redisson客户端。


浙公网安备 33010602011771号