微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于同步方法的 StackExchange.Redis ConnectionMultiplexer 池

如何解决用于同步方法的 StackExchange.Redis ConnectionMultiplexer 池

如果我们将它用于同步方法,实现 ConnectionMultiplexer 池有意义吗?

所以说池我的意思是创建 StackExchange.Redis ConnectionMultiplexer 的多个实例,存储这些对象,当我想与 Redis 服务器通信时,我从池中取出最少使用的一个。这是为了防止根据本文第 10 条建议因大队列而超时:https://azure.microsoft.com/en-us/blog/investigating-timeout-exceptions-in-stackexchange-redis-for-azure-redis-cache/

我有疑问,因为我不确定如果 connectionMultiplexer 阻塞线程直到调用返回,队列怎么会发生。

在我看来,使用同步方法调用池是没有意义的,但 Redis 最佳实践文章建议创建这种池,而不管方法类型(同步/异步)

解决方法

我认为您在这里感到困惑。 ConnectionMultiplexer 不会“被阻止”。创建 ConnectionMultiplexer 为您提供了一个类似工厂的对象,您可以使用它创建 IDatabase 实例。然后,您可以使用这些实例来执行普通的 Redis 查询。您也可以使用连接多路复用器本身执行 Redis 查询,但这些是服务器查询,不太可能经常执行。
因此,简而言之,无论同步/异步/混合使用情况如何,拥有一个连接多路复用器池都非常有用。


为了进一步扩展,这里有一个非常简单的池实现,当然可以进一步增强:

public interface IConnectionMultiplexerPool
{
    Task<IDatabase> GetDatabaseAsync();
}

public class ConnectionMultiplexerPool : IConnectionMultiplexerPool
{
    private readonly ConnectionMultiplexer[] _pool;
    private readonly ConfigurationOptions _redisConfigurationOptions;

    public ConnectionMultiplexerPool(int poolSize,string connectionString) : this(poolSize,ConfigurationOptions.Parse(connectionString))
    {
    }

    public ConnectionMultiplexerPool(int poolSize,ConfigurationOptions redisConfigurationOptions)
    {
        _pool = new ConnectionMultiplexer[poolSize];
        _redisConfigurationOptions = redisConfigurationOptions;
    }

    public async Task<IDatabase> GetDatabaseAsync()
    {
        var leastPendingTasks = long.MaxValue;
        IDatabase leastPendingDatabase = null;

        for (int i = 0; i < _pool.Length; i++)
        {
            var connection = _pool[i];

            if (connection == null)
            {
                _pool[i] = await ConnectionMultiplexer.ConnectAsync(_redisConfigurationOptions);

                return _pool[i].GetDatabase();
            }

            var pending = connection.GetCounters().TotalOutstanding;

            if (pending < leastPendingTasks)
            {
                leastPendingTasks = pending;
                leastPendingDatabase = connection.GetDatabase();
            }
        }

        return leastPendingDatabase;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。