基于Redis的分布式锁设计

本文详细探讨了基于Redis实现分布式锁的过程,从无锁扣减库存问题,到单应用和应用集群中的锁,再到不同版本的改进,如设置过期时间、使用Lua脚本和RedLock算法。作者揭示了实现中的细节问题和优化策略。
摘要由CSDN通过智能技术生成
前言

基于Redis的分布式锁实现,原理很简单嘛:检测一下Key是否存在,不存在则Set Key,加锁成功,存在则加锁失败。对吗?这么简单吗?

如果你真这么想,那么你真的需要好好听我讲一下了。接下来,咱们找个例子研究一下。

在开始之前,咱们先定些规则:

  • 关于示例代码:
    • 需要搭配我准备的示例代码,该示例采用C#编写
    • 示例中的材料Id固定为10000
    • 示例中的材料初始库存均为100
  • 关于Redis中的Key:
    • 指示材料库存的Key为ProductStock_10000
    • 自己实现的分布式锁中,指示锁的Key为DistributedLock_10000
    • RedLock.net中,指示锁的Key为redlock:10000

1、假如没有锁

如果没有锁,我们可以通过Jmeter并发100个请求,看看最后库存是不是0

/// <summary>
/// 无锁扣减库存
/// </summary>
/// <returns></returns>
[HttpPost("DecreaseProductStockWithNoLock")]
public async Task<string> DecreaseProductStockWithNoLock()
{
    var stockKey = GetProductStockKey(ProductId);
    var currentQuantity = (long)(await _redisDatabase.Database.StringGetAsync(stockKey));
    if (currentQuantity < 1)
        throw new Exception("库存不足");

    var leftQuantity = currentQuantity - 1;
    await _redisDatabase.Database.StringSetAsync(stockKey, leftQuantity);

    return $"剩余库存:{leftQuantity}";
}

完了,库存全乱了,收拾收拾,跑路吧o(╥﹏╥)o!

2、单应用中的锁

提到锁,大多数人首先想到的应该就是Monitor的语法糖lock了,这是大多数人最先接触到的一种锁。在单应用中,因为lock是线程锁,所以使用该锁一般是没有什么问题的。

/// <summary>
/// 在单应用中扣减库存
/// </summary>
/// <returns></returns>
[HttpPost("DecreaseProductStockInSingleApp")]
public string DecreaseProductStockInSingleApp()
{
    long leftQuantity;
    lock (_lockObj)
    {
        var stockKey = GetProductStockKey(ProductId);
        var currentQuantity = (long)_redisDatabase.Database.StringGet(stockKey);
        if (currentQuantity < 1)
            throw new Exception("库存不足");

        leftQuantity = currentQuantity - 1;
        _redisDatabase.Database.StringSet(stockKey, leftQuantity);
    }

    return $"剩余库存:{leftQuantity}";
}

结果和我们所期望的一样,剩余库存为0

但是如果我们进行应用集群,部署多份一模一样的应用,那lock就无能为力了。接下来,咱们启动两个应用实例来看看

# 以开发环境运行,能看到更多信息
dotnet XXTk.Redis.DistributedLock.Api.dll --urls http://localhost:5000 --environment Development

dotnet XXTk.Redis.DistributedLock.Api.dll --urls http://localhost:5010 --environment Development

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值