分布式锁 redlock(三)
本文介绍 redlock
github 地址 GitHub - samcook/RedLock.net:C 语言中 Redlock 算法的实现#
该程序集 可以 使用 独立的 非主从复制的 redis 也可以使用 主从复制的redis
他也依赖于 StackExchange.Redis

这种方式 也需要考虑 锁过期时间 和等待时间 只要 加锁数量 大于 redis总数/2 +1 就人为 加锁成功
所以 redis 节点数 最好为 3 5 7 9 奇数个
主从复制的 代码 这是官网上的
var redlockEndPoints = new List<RedLockEndPoint>
{
new RedLockEndPoint
{
EndPoints =
{
new DnsEndPoint("replicatedset1-server1", 6379),
new DnsEndPoint("replicatedset1-server2", 6379),
new DnsEndPoint("replicatedset1-server3", 6379)
}
},
new RedLockEndPoint
{
EndPoints =
{
new DnsEndPoint("replicatedset2-server1", 6379),
new DnsEndPoint("replicatedset2-server2", 6379),
new DnsEndPoint("replicatedset2-server3", 6379)
}
},
new RedLockEndPoint
{
EndPoint = new DnsEndPoint("independent-server", 6379)
}
};
var redlockFactory = RedLockFactory.Create(redlockEndPoints);
非主从复制的
var endPoints = new List<RedLockEndPoint>
{
new DnsEndPoint("redis1", 6379),
new DnsEndPoint("redis2", 6379),
new DnsEndPoint("redis3", 6379)
};
var redlockFactory = RedLockFactory.Create(endPoints);
上测试

上测试代码 测试代码 我只用了 一个redis
public class RedLockTest
{
public static readonly string RedLockKey = "redlock";
public static readonly string RedLockTotalKey = "redlocktotal";
public static async void Test()
{
var existingConnectionMultiplexer1 = ConnectionMultiplexer.Connect("192.168.0.168:6379");
//var existingConnectionMultiplexer2 = ConnectionMultiplexer.Connect("redis2:6379");
//var existingConnectionMultiplexer3 = ConnectionMultiplexer.Connect("redis3:6379");
var multiplexers = new List<RedLockMultiplexer>
{
existingConnectionMultiplexer1,
//existingConnectionMultiplexer2,
//existingConnectionMultiplexer3
};
var redlockFactory = RedLockFactory.Create(multiplexers);
var resource = RedLockTest.RedLockKey;
var expiry = TimeSpan.FromSeconds(30);
var wait = TimeSpan.FromSeconds(10);
var retry = TimeSpan.FromSeconds(1);
//锁的超时时间要大于程序执行的时间,否则多个客户端可能同时获取锁。充分预估使用锁的业务代码执行时间,
//该时间不宜过长也不宜过短,过短,可能使锁发生错误;过长,客户端异常时可能会影响执行效率。
try
{
await using (var redLock = await redlockFactory.CreateLockAsync(resource, expiry, wait, retry)) // there are also non async Create() methods
{
if (!redLock.IsAcquired)
{
Console.WriteLine($"取锁失败,当前线程为{Thread.CurrentThread.ManagedThreadId}");
return;
}
using (RedisClient redisClient = new RedisClient("192.168.0.168:6379"))
{
int total = redisClient.Get<int>(RedLockTest.RedLockTotalKey);
if (total <= 0)
{
Console.WriteLine($"抢购已经结束了{total},当前线程{Thread.CurrentThread.ManagedThreadId}");
return;
}
total -= 1;
redisClient.Set(RedLockTest.RedLockTotalKey, total);
Console.WriteLine($"抢购成功了剩余总数为{total},当前线程为{Thread.CurrentThread.ManagedThreadId}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"报错了{ex.Message}");
}
}
}
浙公网安备 33010602011771号