Kev*_*ter 4 caching redis lazy-initialization stackexchange.redis
我们刚刚开始通过 Web 和辅助角色使用 Azure Redis 缓存。我们发现,在相当少量的使用情况下,创建了约 2.5K 个连接。
我们正在使用包装在连接管理器中的 StackExchange.Redis nuget 包
public class RedisConnManager
{
private readonly IConfiguration configuration;
public RedisConnManager(IConfiguration configuration)
{
this.configuration = configuration;
}
public Lazy<ConnectionMultiplexer> LazyConnection
{
get
{
return new Lazy<ConnectionMultiplexer>(
() => ConnectionMultiplexer.Connect(
this.configuration.SessionManagerRedisConnectionString));
}
}
public ConnectionMultiplexer Connection => this.LazyConnection.Value;
}
Run Code Online (Sandbox Code Playgroud)
然后使用 Ninject 作为单例将该类注入到需要的依赖类中
kernel.Bind<RedisConnManager>().To<RedisConnManager>().InSingletonScope();
Run Code Online (Sandbox Code Playgroud)
然后消费如下
var cache = this.redisConnManager.Connection.GetDatabase();
key = cachable.GenerateKey();
RedisValue result = cache.StringGet(key);
Run Code Online (Sandbox Code Playgroud)
我检查过 ConnectionManager 的构造函数不会被多次调用
我们应该看到这么多联系吗?
LazyConnection每次使用该属性时,您都会创建 Lazy 对象。这是非常错误的。
您应该只创建一次 Lazy 对象,例如在构造函数中:
public class RedisConnManager
{
private readonly IConfiguration configuration;
public RedisConnManager(IConfiguration configuration)
{
this.configuration = configuration;
lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(
configuration.SessionManagerRedisConnectionString));
}
private Lazy<ConnectionMultiplexer> lazyConnection;
public ConnectionMultiplexer Connection { get { return lazyConnection.Value; } }
}
Run Code Online (Sandbox Code Playgroud)
但同样,如果您多次创建该类,您将拥有多个 Lazy 对象,从而产生多个连接。您可能应该静态编码:
public class RedisConnManager
{
private readonly IConfiguration configuration;
public RedisConnManager(IConfiguration configuration)
{
this.configuration = configuration;
lock (locker)
{
if (lazyConnection == null)
{
lazyConnection = new Lazy<ConnectionMultiplexer>(() => new ConnectionMultiplexer(this.configuration));
}
}
}
private static Lazy<ConnectionMultiplexer> lazyConnection;
private static readonly object locker = new object();
public ConnectionMultiplexer Connection { get { return lazyConnection.Value; } }
}
Run Code Online (Sandbox Code Playgroud)
现在lazyConnection是静态的,因此将在该类的所有实例之间共享,并且仅创建一次。额外的锁机制代码是为了避免有多个线程创建惰性对象。
还可以考虑使该configuration字段静态。
| 归档时间: |
|
| 查看次数: |
7447 次 |
| 最近记录: |