分布式缓存架构:Redis集群与数据一致性
分布式缓存架构:Redis集群与数据一致性
概述
分布式缓存是高性能系统的关键组件。本教程介绍Redis集群、数据分片和一致性哈希。
1. Redis集群
import redis.clients.jedis.*;
import java.util.Set;
public class RedisClusterExample {
public static void main(String[] args) {
// 创建Redis集群连接
Set<HostAndPort> nodes = Set.of(
new HostAndPort("localhost", 7000),
new HostAndPort("localhost", 7001),
new HostAndPort("localhost", 7002)
);
JedisCluster cluster = new JedisCluster(nodes);
// 操作
cluster.set("key1", "value1");
String value = cluster.get("key1");
System.out.println("value: " + value);
cluster.close();
}
}
2. 一致性哈希
import java.util.*;
public class ConsistentHash<T> {
private final TreeMap<Long, T> ring = new TreeMap<>();
private final int virtualNodes;
public ConsistentHash(int virtualNodes) {
this.virtualNodes = virtualNodes;
}
public void addNode(T node) {
for (int i = 0; i < virtualNodes; i++) {
long hash = hash(node.toString() + "#" + i);
ring.put(hash, node);
}
}
public void removeNode(T node) {
for (int i = 0; i < virtualNodes; i++) {
long hash = hash(node.toString() + "#" + i);
ring.remove(hash);
}
}
public T getNode(String key) {
if (ring.isEmpty()) {
return null;
}
long hash = hash(key);
Map.Entry<Long, T> entry = ring.ceilingEntry(hash);
if (entry == null) {
entry = ring.firstEntry();
}
return entry.getValue();
}
private long hash(String key) {
return key.hashCode() & 0x7fffffffL;
}
public static void main(String[] args) {
ConsistentHash<String> hash = new ConsistentHash<>(150);
hash.addNode("Node1");
hash.addNode("Node2");
hash.addNode("Node3");
for (int i = 0; i < 10; i++) {
String key = "key" + i;
String node = hash.getNode(key);
System.out.println(key + " -> " + node);
}
}
}
3. 缓存策略
import java.util.concurrent.*;
public class CacheStrategy {
// LRU:最近最少使用
// LFU:最不经常使用
// FIFO:先进先出
// TTL:过期时间
private final Map<String, CacheEntry> cache = new LinkedHashMap<>(100, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<String, CacheEntry> eldest) {
return size() > 1000;
}
};
private static class CacheEntry {
Object value;
long expireTime;
CacheEntry(Object value, long ttl) {
this.value = value;
this.expireTime = System.currentTimeMillis() + ttl;
}
boolean isExpired() {
return System.currentTimeMillis() > expireTime;
}
}
public void put(String key, Object value, long ttl) {
cache.put(key, new CacheEntry(value, ttl));
}
public Object get(String key) {
CacheEntry entry = cache.get(key);
if (entry == null || entry.isExpired()) {
cache.remove(key);
return null;
}
return entry.value;
}
}
4. 实际应用示例
缓存穿透防护
@Service
public class CacheService {
private final RedisTemplate<String, Object> redisTemplate;
// 布隆过滤器
private BloomFilter<String> bloomFilter;
@PostConstruct
public void init() {
bloomFilter = BloomFilter.create(
Funnels.stringFunnel(Charset.defaultCharset()),
1000000,
0.01
);
}
public Object getData(String key) {
// 1. 检查布隆过滤器
if (!bloomFilter.mightContain(key)) {
return null;
}
// 2. 查询缓存
Object value = redisTemplate.opsForValue().get(key);
if (value != null) {
return value;
}
// 3. 查询数据库
value = database.get(key);
if (value != null) {
// 4. 写入缓存
redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
}
return value;
}
}
缓存雪崩防护
@Service
public class CacheService {
public Object getData(String key) {
Object value = redisTemplate.opsForValue().get(key);
if (value == null) {
// 使用分布式锁防止缓存击穿
String lockKey = "lock:" + key;
try {
if (tryLock(lockKey)) {
value = database.get(key);
if (value != null) {
// 随机过期时间,防止缓存雪崩
long ttl = 30 + ThreadLocalRandom.current().nextInt(30);
redisTemplate.opsForValue().set(key, value, ttl, TimeUnit.MINUTES);
}
}
} finally {
unlock(lockKey);
}
}
return value;
}
}
5. 最佳实践
- 选择合适的缓存策略:根据业务需求选择LRU、LFU等
- 设置合理的过期时间:避免缓存雪崩
- 使用布隆过滤器:防止缓存穿透
- 使用分布式锁:防止缓存击穿
- 监控缓存命中率:优化缓存策略
总结
分布式缓存是高性能系统的关键组件。掌握Redis集群、一致性哈希和缓存策略,可以构建高效的缓存架构。