分布式锁深度实战:从 Redis 到 Zookeeper 深度解析

分布式锁深度实战:从 Redis 到 Zookeeper 深度解析


核心要点

分布式锁是分布式系统中保证资源互斥访问的核心技术:

  • 需要理解分布式锁的三大必要条件(互斥、无死锁、高可用)
  • 需要掌握 Redis 和 Zookeeper 分布式锁的实现原理
  • 需要了解 Redis AP 系统和 Zookeeper CP 系统的本质区别
  • 需要深入理解 Redisson 看门狗机制和 Curator 框架的羊群效应优化

本文将深入对比 Redis 和 Zookeeper 分布式锁的实现原理,帮助你在实际项目中做出正确的技术选型。


一、分布式锁基础

1.1 为什么需要分布式锁

在分布式系统中,多个服务实例可能同时访问共享资源,我们需要一种机制来保证资源在同一时刻只能被一个实例访问:
解决方案:分布式锁
分布式锁
Redis 实现
Zookeeper 实现
资源互斥访问
分布式场景:本地锁失效
用户请求
Tomcat 集群
多个实例同时竞争
synchronized 只在单实例有效
数据不一致!
单机场景:本地锁够用
用户请求
Tomcat 实例
synchronized 互斥
访问共享资源

1.2 分布式锁应满足的条件

一个合格的分布式锁必须满足以下条件:
分布式锁必要条件
互斥性

任意时刻只能有一个客户端持有锁
无死锁

锁在持有客户端崩溃时能自动释放
原子性

加锁和解锁操作必须是原子的
可重入

同一客户端可多次获取同一把锁
高性能

高并发下性能要足够好

条件 说明 实现方式
互斥性 任意时刻只能有一个客户端持有锁 SETNX、临时顺序节点
无死锁 持有锁的客户端崩溃后,锁能自动释放 TTL 过期、临时节点自动删除
原子性 加锁和解锁必须是原子操作 Lua 脚本、事务
可重入 同一客户端可多次获取同一把锁 锁计数器、线程 ID 记录
高性能 高并发下性能要足够好 Redis QPS 10万+

1.3 本地锁 vs 分布式锁

特性 本地锁 分布式锁
作用范围 单 JVM 进程 多 JVM 进程/多机器
实现方式 synchronized、ReentrantLock Redis SETNX、Zookeeper 临时节点
性能 非常高(无网络开销) 有网络开销
可靠性 单点故障 依赖外部系统可靠性
复杂度 简单 复杂

1.4 典型应用场景

应用场景
秒杀场景
库存扣减
保证库存不超卖
分布式任务
订单处理
保证幂等性
定时任务
资源分配
保证唯一执行

场景 说明 分布式锁作用
秒杀/抢购 同一商品同时只能被一个用户购买 库存扣减时加锁,防止超卖
订单处理 同一订单只能被处理一次 防止重复处理
定时任务 同一任务只能被执行一次 防止重复执行
ID 生成器 全局唯一 ID 防止 ID 重复
乐观锁更新 防止并发更新冲突 CAS 操作的变体

二、Redis 分布式锁

2.1 Redis 分布式锁实现原理

Redis 分布式锁的核心是 SET key value NX EX seconds 命令,这条命令保证加锁操作的原子性:
Redis SETNX 加锁流程
成功
失败
SET lock_key unique_id NX EX 30
返回 OK?
获取锁成功
获取锁失败,返回 false
执行业务逻辑
释放锁(Lua 脚本)

2.2 Redis SETNX 基础实现

java 复制代码
/**
 * Redis 分布式锁基础实现
 */
public class RedisDistributedLock {
    
    private RedisTemplate<String, String> redisTemplate;
    
    /**
     * 尝试获取锁
     * @param lockKey 锁的 key
     * @param requestId 客户端唯一标识(UUID)
     * @param expireTime 过期时间(秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long expireTime) {
        // SET key value NX EX seconds - 原子性操作
        Boolean result = redisTemplate.opsForValue()
            .setIfAbsent(lockKey, requestId, 
                Duration.ofSeconds(expireTime));
        return Boolean.TRUE.equals(result);
    }
    
    /**
     * 释放锁 - 使用 Lua 脚本保证原子性
     * @param lockKey 锁的 key
     * @param requestId 客户端唯一标识
     * @return 是否释放成功
     */
    public boolean releaseLock(String lockKey, String requestId) {
        // Lua 脚本:只有锁的值等于请求 ID 时才删除
        String luaScript = 
            "if redis.call('get', KEYS[1]) == ARGV[1] then " +
            "    return redis.call('del', KEYS[1]) " +
            "else " +
            "    return 0 " +
            "end";
        
        Long result = redisTemplate.execute(
            new DefaultRedisScript<>(luaScript, Long.class),
            Collections.singletonList(lockKey),
            requestId
        );
        
        return result != null && result > 0;
    }
}

2.3 Redisson 实现机制(看门狗、自动续期)

Redisson 是 Java 中最流行的 Redis 客户端之一,其分布式锁实现包含了完善的看门狗机制:
TTL 续期示例
初始 TTL = 30秒
10秒后:第一次续期 → TTL = 30秒
20秒后:第二次续期 → TTL = 30秒
...
Redisson 看门狗机制


获取锁成功
启动看门狗定时器
每 1/3 TTL 时间检查
锁仍被当前客户端持有?
续期 TTL
不做任何操作

java 复制代码
/**
 * Redisson 分布式锁完整使用示例
 */
public class RedissonLockExample {
    
    private RedissonClient redissonClient;
    
    /**
     * 获取锁(可重入)
     */
    public void executeWithLock(String lockKey, Runnable task) {
        // 1. 获取锁(默认 TTL = 30秒,看门狗自动续期)
        RLock lock = redissonClient.getLock(lockKey);
        
        try {
            // 2. 尝试获取锁,等待 10 秒,锁定 30 秒
            // waitTime = 10s:等待获取锁的最大时间
            // leaseTime = 30s:锁的自动释放时间
            // 如果设置 leaseTime,看门狗不会生效
            // 如果不设置 leaseTime,看门狗会自动续期
            boolean locked = lock.tryLock(10, 30, TimeUnit.SECONDS);
            
            if (locked) {
                try {
                    // 3. 执行业务逻辑
                    task.run();
                } finally {
                    // 4. 释放锁
                    if (lock.isHeldByCurrentThread()) {
                        lock.unlock();
                    }
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 公平锁示例
     */
    public void fairLockExample(String lockKey, Runnable task) {
        // 获取公平锁(FIFO 顺序获取)
        RLock fairLock = redissonClient.getFairLock(lockKey);
        
        try {
            fairLock.lock();
            task.run();
        } finally {
            fairLock.unlock();
        }
    }
    
    /**
     * 读写锁示例
     */
    public void readWriteLockExample(String lockKey) {
        RReadWriteLock rwLock = redissonClient.getReadWriteLock(lockKey);
        
        // 读锁:多个线程可以同时持有
        RLock readLock = rwLock.readLock();
        readLock.lock();
        try {
            // 读取操作
        } finally {
            readLock.unlock();
        }
        
        // 写锁:独占
        RLock writeLock = rwLock.writeLock();
        writeLock.lock();
        try {
            // 写入操作
        } finally {
            writeLock.unlock();
        }
    }
}

2.4 RedLock 红锁算法原理

RedLock 是 Redis 作者 Antirez 提出的分布式锁算法,用于提高分布式锁的可靠性:
RedLock 示意图
加锁成功
加锁成功
加锁成功
加锁失败
加锁失败
Redis 1

Redis 2

Redis 3

Redis 4

Redis 5

成功 3/5 >= 3
RedLock 红锁算法


获取 N 个 Redis 实例
在 N 个实例上获取锁
成功获取 >= N/2+1 个锁?
获取锁成功
获取锁失败,释放所有锁
执行业务逻辑
释放所有实例的锁

2.5 Redis 分布式锁的坑

Redis 分布式锁常见问题
主从切换问题

Master 宕机,Slave 未同步锁
新 Master 没有锁数据
其他客户端获取同一把锁
时钟漂移问题

Redisson 使用定时器续期
如果时间回拨,可能提前释放
锁过期业务未完成

业务执行时间超过 TTL
业务还没执行完,锁就释放了
其他客户端进入,数据不一致
非原子性操作

check-then-act 模式
检查锁存在后再操作
中间可能被其他客户端篡改

问题 原因 解决方案
主从切换导致锁丢失 Redis 主从异步复制 使用 RedLock,需要多个独立 Redis 实例
时钟漂移 分布式系统时间不同步 Redisson 使用单节点内时间,外部时间漂移不影响
锁提前释放 业务执行时间 > TTL 看门狗自动续期,或设置合理 TTL + 业务异步补偿
非原子性 check-then-act 使用 Lua 脚本保证原子性

三、Zookeeper 分布式锁

3.1 Zookeeper 数据模型

Zookeeper 是一个分布式协调服务,其核心是树形数据结构和 Watch 机制:
节点类型
PERSISTENT

持久节点
EPHEMERAL

临时节点(客户端断开自动删除)
SEQUENCE

顺序节点(自动编号)
Zookeeper 数据模型
根节点 /
/locks
/locks/order-0000000001
/locks/order-0000000002
/locks/order-0000000003
临时顺序节点
临时顺序节点
临时顺序节点

3.2 临时顺序节点实现分布式锁原理

Zookeeper 释放锁流程
客户端 A 断开连接
临时节点自动删除
通知监听该节点的客户端
客户端 B 成为最小节点
获取锁成功
Zookeeper 获取锁流程


客户端 A 创建临时顺序节点

/locks/order-0000000001
获取 /locks 下所有子节点
判断自己是否是最小节点?
获取锁成功
Watcher 监听前一个节点
等待前一个节点删除
收到通知,再次检查

3.3 Curator 框架使用

java 复制代码
/**
 * Curator 分布式锁完整使用示例
 */
public class CuratorLockExample {
    
    private CuratorFramework curatorClient;
    
    /**
     * 初始化 Curator 客户端
     */
    @PostConstruct
    public void init() {
        curatorClient = CuratorFrameworkFactory.builder()
            .connectString("localhost:2181")
            .sessionTimeoutMs(5000)
            .connectionTimeoutMs(3000)
            .retryPolicy(new ExponentialBackoffRetry(1000, 3))
            .build();
        curatorClient.start();
    }
    
    /**
     * 获取分布式排他锁
     */
    public void executeWithLock(String lockPath, Runnable task) throws Exception {
        // 1. 创建排他锁
        InterProcessMutex lock = new InterProcessMutex(curatorClient, lockPath);
        
        try {
            // 2. 获取锁(等待 10 秒)
            if (lock.acquire(10, TimeUnit.SECONDS)) {
                try {
                    // 3. 执行业务逻辑
                    task.run();
                } finally {
                    // 4. 释放锁
                    lock.release();
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("获取锁失败", e);
        }
    }
    
    /**
     * 可重入排他锁
     */
    public void reentrantLockExample(String lockPath, Runnable task) throws Exception {
        InterProcessMutex lock = new InterProcessMutex(curatorClient, lockPath);
        
        // 同一线程可以多次获取锁
        lock.acquire(10, TimeUnit.SECONDS);
        lock.acquire(10, TimeUnit.SECONDS);  // 可重入
        try {
            task.run();
        } finally {
            lock.release();
            lock.release();  // 需要对应释放次数
        }
    }
    
    /**
     * 读写锁示例
     */
    public void readWriteLockExample(String lockPath) throws Exception {
        InterProcessReadWriteLock rwLock = 
            new InterProcessReadWriteLock(curatorClient, lockPath);
        
        // 获取读锁(共享锁,多个线程可同时持有)
        InterProcessMutex readLock = rwLock.readLock();
        readLock.acquire(10, TimeUnit.SECONDS);
        try {
            // 读取操作
        } finally {
            readLock.release();
        }
        
        // 获取写锁(独占锁)
        InterProcessMutex writeLock = rwLock.writeLock();
        writeLock.acquire(10, TimeUnit.SECONDS);
        try {
            // 写入操作
        } finally {
            writeLock.release();
        }
    }
    
    /**
     * 多锁对象(同时获取多个锁)
     */
    public void multiLockExample(String lockPath1, String lockPath2, Runnable task) 
            throws Exception {
        InterProcessMutex lock1 = new InterProcessMutex(curatorClient, lockPath1);
        InterProcessMutex lock2 = new InterProcessMutex(curatorClient, lockPath2);
        
        // 同时获取多个锁
        InterProcessMultiLock multiLock = 
            new InterProcessMultiLock(lock1, lock2);
        
        if (multiLock.acquire(10, TimeUnit.SECONDS)) {
            try {
                task.run();
            } finally {
                multiLock.release();
            }
        }
    }
}

3.4 Curator 分布式锁实现原理

羊群效应优化
无优化:所有客户端监听第一个节点
第一个节点删除,所有客户端都被通知
大量无效 Watch 事件
优化后:每个客户端只监听前一个节点
有序通知,精确唤醒
Watch 事件数量 O(n) → O(1)
Curator 分布式锁实现原理


创建临时顺序节点
获取锁路径下所有子节点
子节点按编号排序
自己是第一个?
获取锁成功
Watch 前一个节点
等待前一个节点删除
收到删除事件
重新检查排序

3.5 Zookeeper 分布式锁的优缺点

优点 说明
可靠性高 Zookeeper 使用 ZAB 协议,保证分布式一致性
自动释放 临时节点在客户端断开时自动删除,无死锁
有序性 顺序节点天然保证锁的获取顺序
成熟方案 Curator 框架封装完善,经过大量生产验证
缺点 说明
性能较低 每次获取锁都需要创建节点、Watcher 通知,有网络开销
吞吐量有限 Zookeeper 每个写操作需要 Leader 广播,不适合高并发
运维复杂 需要维护 Zookeeper 集群,增加运维成本
锁粒度 不支持公平锁(社区版),需要额外实现

四、两种方案对比

4.1 Redis vs Zookeeper 分布式锁

对比维度
CAP 理论
Redis: AP 系统

高可用 + 分区容忍
Zookeeper: CP 系统

一致性 + 分区容忍
性能
Redis: QPS 10万+

纯内存操作
Zookeeper: QPS 1万

需要 Leader 协调
可靠性
Redis: 依赖 Redis 本身

需要 RedLock 提高可靠性
Zookeeper: ZAB 协议保证

一致性更强
功能特性
Redis: 看门狗自动续期

可重入、公平锁、读写锁
Zookeeper: 临时顺序节点

Watch 机制、天然有序
运维成本
Redis: 简单,Redis 本身需要维护
Zookeeper: 复杂,需要维护 ZK 集群

对比维度 Redis 分布式锁 Zookeeper 分布式锁
CAP 模型 AP(高可用、分区容忍) CP(一致性、分区容忍)
实现原理 SETNX + TTL 临时顺序节点 + Watch
性能 非常高(10万+ QPS) 较低(1万 QPS)
可靠性 依赖 Redis 本身 ZAB 协议保证
锁释放 TTL 自动过期 临时节点自动删除
锁续期 看门狗自动续期 不需要(持有锁=连接存在)
羊群效应 通过顺序节点优化
运维复杂度
适用场景 高并发、对性能要求高 对一致性要求极高

4.2 选型决策树









开始选型
对一致性要求极高?
选择 Zookeeper
并发量超过 5万/秒?
选择 Redis
需要自动续期?
选择 Redis + Redisson
已有 Zookeeper 集群?
选择 Zookeeper
选择 Redis


五、分布式锁升级策略

5.1 锁粒度设计

分段锁(折中方案)
将数据分成 N 段
每段一个锁
N = 线程数 × 2
细粒度锁
锁住单行数据
复杂,但并发高
按 ID 哈希分配锁
粗粒度锁
锁住整个表
简单,但并发低
所有操作串行化

5.2 锁升级策略

升级路径


读多写少场景
共享锁(读锁)
写入需求?
升级为排他锁
继续持有读锁
轻量级锁 → 重量级锁
自旋锁重试次数超限
阻塞等待
单实例锁 → 分布式锁
单点故障风险
引入 RedLock


六、最佳实践与避坑

6.1 常见问题案例

案例3:Redis 单点故障
Redis Master 宕机
哨兵自动切换
Slave 未同步锁数据
新 Master 没有锁
其他客户端获取同一把锁
解决方案:使用 RedLock
案例2:释放了别人的锁
客户端 A 获取锁
业务执行超时
锁自动释放
客户端 B 获取锁
客户端 A 执行完毕
错误释放了 B 的锁
解决方案:使用唯一 requestId
案例1:锁过期业务未完成
TTL = 5秒
业务执行 10 秒
5 秒后锁自动释放
其他客户端进入
数据不一致!
解决方案:看门狗自动续期

6.2 锁设计原则

原则 说明 示例
锁粒度要合理 锁太粗性能差,锁太细管理复杂 库存场景:按 SKU 分段锁
TTL 要充足 TTL = 业务执行时间 × 2 + buffer 业务 5 秒 → TTL 至少 15 秒
异常必须释放锁 finally 中释放,防止死锁 try-finally-unlock
使用唯一标识 防止误释放他人持有的锁 UUID 作为 requestId
考虑幂等性 解锁失败、锁续期失败怎么办 业务逻辑支持重试
监控告警 监控锁等待时间、获取成功率 Prometheus + Grafana

6.3 完整代码实现

java 复制代码
/**
 * 分布式锁最佳实践完整实现
 */
@Component
public class DistributedLockTemplate {
    
    private RedissonClient redissonClient;
    private PrometheusMeterRegistry meterRegistry;
    
    /**
     * 通用分布式锁执行模板
     */
    public <T> T executeWithLock(String lockKey, 
                                  Supplier<T> supplier,
                                  int waitTimeSeconds,
                                  int leaseTimeSeconds) {
        RLock lock = redissonClient.getLock(lockKey);
        Timer.Sample sample = Timer.start(meterRegistry);
        
        try {
            // 1. 尝试获取锁,记录等待时间
            boolean acquired = lock.tryLock(waitTimeSeconds, 
                                            leaseTimeSeconds, 
                                            TimeUnit.SECONDS);
            
            if (!acquired) {
                // 获取锁失败,记录指标
                meterRegistry.counter("lock.failed", 
                    Tags.of("key", lockKey)).increment();
                throw new LockAcquisitionException(
                    "获取分布式锁失败: " + lockKey);
            }
            
            // 2. 获取成功,执行业务
            meterRegistry.counter("lock.success", 
                Tags.of("key", lockKey)).increment();
            
            return supplier.get();
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new LockAcquisitionException("获取锁被中断", e);
        } finally {
            // 3. 释放锁(必须)
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
            
            // 4. 记录执行时间
            sample.stop(Timer.builder("lock.execution")
                .tag("key", lockKey)
                .register(meterRegistry));
        }
    }
    
    /**
     * 库存扣减示例
     */
    public boolean deductStock(String productId, int quantity) {
        String lockKey = "stock:lock:" + productId;
        
        return executeWithLock(lockKey, () -> {
            // 1. 查询当前库存
            Integer stock = getStockFromDB(productId);
            
            // 2. 检查库存是否充足
            if (stock < quantity) {
                return false;  // 库存不足
            }
            
            // 3. 扣减库存
            updateStockInDB(productId, stock - quantity);
            
            return true;
        }, 5, 30);  // 等待 5 秒,TTL 30 秒
    }
    
    /**
     * 分布式任务执行(幂等保证)
     */
    public void executeTaskOnce(String taskId, Runnable task) {
        String lockKey = "task:lock:" + taskId;
        
        // 使用 tryLock 模式,避免阻塞
        RLock lock = redissonClient.getLock(lockKey);
        
        if (lock.tryLock()) {
            try {
                // 双重检查:Redis + 数据库
                if (isTaskExecuted(taskId)) {
                    return;  // 已执行,直接返回
                }
                
                // 执行业务
                task.run();
                
                // 标记任务完成
                markTaskExecuted(taskId);
                
            } finally {
                lock.unlock();
            }
        } else {
            // 未获取到锁,说明有其他实例在执行
            log.info("任务 {} 正在被其他实例执行", taskId);
        }
    }
    
    // 辅助方法
    private Integer getStockFromDB(String productId) { /* ... */ return 0; }
    private void updateStockInDB(String productId, int stock) { /* ... */ }
    private boolean isTaskExecuted(String taskId) { return false; }
    private void markTaskExecuted(String taskId) { /* ... */ }
}

七、面试高频问题

7.1 Redis 分布式锁问题

Q1:Redis 分布式锁如何保证原子性?

A1:Redis 分布式锁的原子性通过以下机制保证:

  • 加锁原子性 :使用 SET key value NX EX seconds 命令,这是 Redis 单命令操作,保证原子性
  • 释放锁原子性:使用 Lua 脚本释放锁,先检查值是否匹配,再删除
lua 复制代码
-- 释放锁的 Lua 脚本
if redis.call('get', KEYS[1]) == ARGV[1] then
    return redis.call('del', KEYS[1])
else
    return 0
end

Q2:Redis 分布式锁过期了业务还没执行完怎么办?

A2:解决方案有两种:

  1. 看门狗机制(推荐):Redisson 实现了看门狗,每 1/3 TTL 时间自动续期,只要客户端存活,锁就不会释放
  2. 设置合理 TTL + 异步补偿:预估业务执行时间,设置充足的 TTL + buffer,业务执行失败时通过消息队列重试

Q3:Redis 主从模式下锁丢失问题如何解决?

A3:Redis 主从异步复制可能导致以下问题:

  1. Master 宕机时,锁数据未同步到 Slave
  2. Sentinel/Cluster 自动切换后,新 Master 没有锁数据

解决方案是使用 RedLock 算法:

  1. 在 N 个独立的 Redis 实例上获取锁
  2. 只有成功获取 >= N/2+1 个锁,才认为获取成功
  3. 这样即使部分实例宕机,也不会丢失锁

7.2 Zookeeper 分布式锁问题

Q4:Zookeeper 分布式锁如何实现公平锁?

A4:Zookeeper 的顺序节点天然保证了公平性:

  1. 每个请求在 /locks 路径下创建临时顺序节点
  2. 最小序号节点获取锁,其他节点等待
  3. 由于是顺序节点,锁的获取顺序就是创建顺序(FIFO)

注意:Curator 的 InterProcessMutex 默认就是公平锁。

Q5:Zookeeper 的羊群效应是什么?如何优化?

A5:羊群效应是指大量客户端同时监听同一个节点变化。当这个节点被删除时,所有客户端都会收到通知,导致大量无效的 Watch 事件。

优化方案:使用临时顺序节点,每个客户端只监听前一个节点,而不是第一个节点。这样只有前一个节点被删除时,才会通知下一个客户端,实现了精确唤醒。

7.3 选型问题

Q6:Redis 和 Zookeeper 分布式锁如何选型?

A6:选型依据主要是业务场景:

场景 推荐方案 原因
高并发(10万+ QPS) Redis 性能高,延迟低
强一致性(金融、订单) Zookeeper CP 模型,ZAB 协议保证
简单场景 Redis 运维简单,Redisson 功能完善
已有 Zookeeper Zookeeper 复用现有基础设施
需要自动续期 Redis + Redisson 看门狗机制
跨数据中心 Zookeeper 更强的分布式一致性

八、总结

8.1 核心要点回顾

选型建议
高并发 → Redis
强一致 → Zookeeper
通用场景 → Redis + Redisson
Zookeeper分布式锁
临时顺序节点
Watcher 监听前一个
羊群效应优化
自动释放无死锁
Redis分布式锁
SETNX + TTL
看门狗自动续期
Lua 脚本释放锁
RedLock 提高可靠性

8.2 Redis vs Zookeeper 对比总结

维度 Redis Zookeeper
CAP AP CP
性能 10万+ QPS 1万 QPS
可靠性 需要 RedLock ZAB 协议保证
锁释放 TTL 自动过期 临时节点删除
适用场景 高并发 强一致性
运维成本

8.3 实战建议

  1. 优先选择 Redis:大多数场景下 Redis 分布式锁足够使用,性能更好
  2. 使用成熟框架:Redisson 封装完善,Curator 功能丰富
  3. 注意异常处理:锁获取失败要有降级方案
  4. 做好监控:监控锁等待时间、获取成功率等指标
  5. 考虑幂等性:业务逻辑要支持锁相关的重试

参考资料

  1. Redis 官方文档:https://redis.io/docs/
  2. Redisson 官方文档:https://redisson.org/
  3. Zookeeper 官方文档:https://zookeeper.apache.org/
  4. Curator 官方文档:https://curator.apache.org/
  5. RedLock 论文:https://redis.io/topics/distlock
  6. 《Redis 设计与实现》
  7. 《从 Paxos 到 Zookeeper》
相关推荐
LoneEon1 小时前
Kafka集群搭建指南:KRaft模式彻底摒弃Zookeeper
分布式·kafka·centos
码上小翔哥1 小时前
Spring Boot Redis 缓存序列化踩坑记:GenericJackson2JsonRedisSerializer 的数组反序列化陷阱
java·redis
Devin~Y1 小时前
大厂Java面试实战:Spring Boot/Cloud、Redis/Kafka、JVM调优与Spring AI RAG(内容社区UGC+AIGC客服场景)
java·jvm·spring boot·redis·spring cloud·kafka·mybatis
学习中.........1 小时前
高并发架构下的 Kafka 与消息队列核心机制
分布式·kafka
Han.miracle1 小时前
分布式部署项目
分布式
努力努力再努力wz2 小时前
【Redis 入门系列】为什么需要 Redis?一文串起缓存、分布式、读写分离、分库分表与微服务
数据库·redis·分布式·sql·mysql·缓存·微服务
番茄去哪了2 小时前
单体转微服务:微服务保护和分布式事务(上)
分布式·微服务·架构
念何架构之路2 小时前
分布式详解
分布式
韩小兔修媛史2 小时前
Redis面试八股文总结
数据库·redis·面试