使用StackExchange.Redis的正确方法

13

这个想法是使用更少的连接以获得更好的性能。 连接是否会在任何时候过期?

另一个问题是,_redis.GetDatabase() 是否会打开新的连接?

private static ConnectionMultiplexer _redis;
private static IDatabase _db;

public RedisCacheProvider(string configuration)
{
    if (_redis == null)
        lock (myLock)
            if (_redis == null)
            {
                _redis = ConnectionMultiplexer.Connect(configuration);
                _db = _redis.GetDatabase();
            }
}

public async Task<string> GetString(string key)
{
    string result = null;

    RedisValue val = await _db.StringGetAsync(key);

    if (val.HasValue)
        result = val;

    return result;
}
1个回答

22
不,多路复用器不会过期。GetDatabase不会打开新连接。这些都在basics.md中有所涵盖-特别是:

从GetDatabase返回的对象是一个廉价的透传对象,并且不需要被存储。

1
使用静态IDatabase对象与每次调用其方法时调用GetDatabase之间是否存在性能影响? - Aaron
@Aaron 对于数据库0-15且没有异步状态的情况,在最近的构建版本中完全没有开销。(注意:.GetDatabase()是没有异步状态的db 0,因此没有开销)。对于旧版本、大于15的数据库或有异步状态的情况,只分配一个对象,开销很小。 - Marc Gravell
1
@tehmas 我的意思是它只是一个令牌类,携带复用器、选择的数据库编号和(很少)状态对象;对于“低”数据库编号(根据我的任意定义),在复用器级别上也有很大可能会被记忆化,即如果您调用 GetDatabase(2) 3 次,您可能会得到相同的对象 3 次,而不是 3 个不同的对象;但无论哪种方式:它都不需要任何事情——调用 GetDatabase 不会与服务器通信等。 - Marc Gravell
1
@tehmas 我需要看代码;简短的版本是:你不能这样做,所以我认为问题在于你的测试装置;这里是代码 - 你可以看到,除了验证参数之外,它什么也不做,只返回一个预先存在的实例或一个新的简单对象。 - Marc Gravell
1
@tehmas 如果你想知道“构造函数是否与多路复用器通信”,答案是不会:https://github.com/StackExchange/StackExchange.Redis/blob/master/src/StackExchange.Redis/RedisDatabase.cs#L12-L16 和 https://github.com/StackExchange/StackExchange.Redis/blob/master/src/StackExchange.Redis/RedisBase.cs#L13-L17 - Marc Gravell
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接