C# StackExchange.Redis ConnectionMultiplexer建议的配置
我正在使用StackExchange.Redis中的锁功能(LockTake和LockRelease),但需要保持它基本上是不断轮询的。我让它以0到10毫秒的随机间隔睡眠,然后再试一次。我敢打赌这基本上是连接起来的 我发现的文档建议(几乎)总是只使用1个ConnectionMultiplexer,它只会连接到Redis,但我也相信这是由于该连接的预期可用性。我最多有125个潜在线程需要同时调用Redis。我可以使用连接池,但是在这种情况下,池中应该有多少个ConnectionMultiplexer 编辑 在下面的评论中与Marc讨论后,切换到Pub/Sub,但仍然使用连接池,下面是代码: 这里是TakeLock方法C# StackExchange.Redis ConnectionMultiplexer建议的配置,c#,redis,stackexchange.redis,C#,Redis,Stackexchange.redis,我正在使用StackExchange.Redis中的锁功能(LockTake和LockRelease),但需要保持它基本上是不断轮询的。我让它以0到10毫秒的随机间隔睡眠,然后再试一次。我敢打赌这基本上是连接起来的 我发现的文档建议(几乎)总是只使用1个ConnectionMultiplexer,它只会连接到Redis,但我也相信这是由于该连接的预期可用性。我最多有125个潜在线程需要同时调用Redis。我可以使用连接池,但是在这种情况下,池中应该有多少个ConnectionMultiplexe
private Task TakeLockAsync(string key, string value)
{
TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
var task = taskCompletionSource.Task;
var db = _dbFactory.GetDatabase();
//if we can get the lock, do it and return
bool gotLockTry1 = db.LockTake(key, value, _redisLockConfig.RedisLockMaxAgeTimeSpan);
if (gotLockTry1)
{
taskCompletionSource.SetResult(true);
return task;
}
// if we failed to get the lock,
// set up a subscriber to listen for lock release publish
var subscriber = db.Multiplexer.GetSubscriber();
Action<RedisChannel, RedisValue> handler = null;
handler = (redisChannel, redisValue) =>
{
bool gotLockTry3 = db.LockTake(key, value, _redisLockConfig.RedisLockMaxAgeTimeSpan);
if (gotLockTry3)
{
subscriber.Unsubscribe(_subscriptionChannelName, handler);
taskCompletionSource.SetResult(true);
}
};
subscriber.Subscribe(_subscriptionChannelName, handler);
// double check to make sure a release didn't come through while subscribing
bool gotLockTry2 = db.LockTake(key, value, _redisLockConfig.RedisLockMaxAgeTimeSpan);
if (gotLockTry2)
{
subscriber.Unsubscribe(_subscriptionChannelName, handler);
taskCompletionSource.SetResult(true);
return task;
}
return task;
}
我想知道酒吧/酒吧是否是这里的去处。因此,通过pub/sub进行投票或激活的间隔较长,以先到者为准。显然,在释放锁的代码中有一个“pub”。这对你有用吗?@MarcGravel我之前确实尝试过,但有问题。事实证明,我们在负载均衡器后面有一个redis服务器集群,而不是主/从集群,所以它现在可能工作得很好。你有没有一个猜测,我需要多少连接使用的只是轮询虽然?也许只是数量级(10或100)?@MarcGravel我将我的redis锁切换为使用pub/sub。我创建了一个执行锁的端点,然后在其中有半秒的睡眠时间。当使用1 ConnectionMultiplexer运行此程序时,它将挂起。它实际上没有删除密钥,尽管我不知道为什么。当我将连接数增加到10时,它工作正常。如果没有你的消息,我会选择10个连接的酒吧/酒吧(每台机器,总共40个),但是我很想听听你的建议。我需要看一些伪代码来评论挂起。至于投票。。。。这取决于有多少事情是并行的。即使一个线程正在循环,thst也不会阻止其他线程使用混合器,尽管它会增加服务器和网络负载。这可能还是个好主意。但我想知道是否有更好的办法让我考虑一种更好的/可支持的方法来实现这一点,并将其嵌入到库中。@MarcGravel我编辑了我的问题,以包含代码。不过,在我使用这种发布/订阅锁定机制之前,我会先考虑内置一个连接池。我想知道发布/订阅是否是解决这个问题的方法。因此,通过pub/sub进行投票或激活的间隔较长,以先到者为准。显然,在释放锁的代码中有一个“pub”。这对你有用吗?@MarcGravel我之前确实尝试过,但有问题。事实证明,我们在负载均衡器后面有一个redis服务器集群,而不是主/从集群,所以它现在可能工作得很好。你有没有一个猜测,我需要多少连接使用的只是轮询虽然?也许只是数量级(10或100)?@MarcGravel我将我的redis锁切换为使用pub/sub。我创建了一个执行锁的端点,然后在其中有半秒的睡眠时间。当使用1 ConnectionMultiplexer运行此程序时,它将挂起。它实际上没有删除密钥,尽管我不知道为什么。当我将连接数增加到10时,它工作正常。如果没有你的消息,我会选择10个连接的酒吧/酒吧(每台机器,总共40个),但是我很想听听你的建议。我需要看一些伪代码来评论挂起。至于投票。。。。这取决于有多少事情是并行的。即使一个线程正在循环,thst也不会阻止其他线程使用混合器,尽管它会增加服务器和网络负载。这可能还是个好主意。但我想知道是否有更好的办法让我考虑一种更好的/可支持的方法来实现这一点,并将其嵌入到库中。@MarcGravel我编辑了我的问题,以包含代码。不过,在使用这种发布/订阅锁定机制之前,我会先考虑内置一个连接池。
public void Dispose()
{
if (string.IsNullOrEmpty(_key) || string.IsNullOrEmpty(_value))
{
return;
}
var db = _dbFactory.GetDatabase();
//nested transactions not allowed, so can't call LockReleaseAsync
var trans = db.CreateTransaction();
// http://redis.io/topics/distlock
// remove the key only if it exists and the value matches key's value
trans.AddCondition(Condition.StringEqual(_key, _value));
trans.KeyDeleteAsync(_key);
trans.PublishAsync(_subscriptionChannelName, "something else here");
//runs only when execute called
trans.Execute();
}