C# StackExchange.Redis ConnectionMultiplexer建议的配置

C# StackExchange.Redis ConnectionMultiplexer建议的配置,c#,redis,stackexchange.redis,C#,Redis,Stackexchange.redis,我正在使用StackExchange.Redis中的锁功能(LockTake和LockRelease),但需要保持它基本上是不断轮询的。我让它以0到10毫秒的随机间隔睡眠,然后再试一次。我敢打赌这基本上是连接起来的 我发现的文档建议(几乎)总是只使用1个ConnectionMultiplexer,它只会连接到Redis,但我也相信这是由于该连接的预期可用性。我最多有125个潜在线程需要同时调用Redis。我可以使用连接池,但是在这种情况下,池中应该有多少个ConnectionMultiplexe

我正在使用StackExchange.Redis中的锁功能(LockTake和LockRelease),但需要保持它基本上是不断轮询的。我让它以0到10毫秒的随机间隔睡眠,然后再试一次。我敢打赌这基本上是连接起来的

我发现的文档建议(几乎)总是只使用1个ConnectionMultiplexer,它只会连接到Redis,但我也相信这是由于该连接的预期可用性。我最多有125个潜在线程需要同时调用Redis。我可以使用连接池,但是在这种情况下,池中应该有多少个ConnectionMultiplexer

编辑

在下面的评论中与Marc讨论后,切换到Pub/Sub,但仍然使用连接池,下面是代码:

这里是TakeLock方法

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();
    }