【发布时间】:2016-11-15 23:39:53
【问题描述】:
当一个新机器启动(或者可能是应用程序池被回收)时,我们会看到每个 redis 请求的超时错误。有趣的是,大概是1/30左右。也就是说,30 个盒子可以正常启动并工作(实际调用是 Redis Lock 调用),每 1 个盒子在这种故障状态下启动。下面的示例显示队列中的 9k 个项目。根据 MS azure 建议(尽管我们不在 Azure 上),ConnectionMultiplexer 正在延迟初始化,调用如下:
var db = m_dbFactory.GetDatabase();
bool gotLock = db.LockTake(key, value, m_redisLockConfig.RedisLockMaxAgeTimeSpan);
我们正在使用 Ninject 来获取注入的 dbFactory 的单例:
kernel.Bind<IRedisDatabaseFactory>().To<RedisDatabaseFactory>().InSingletonScope();
我们不得不重新部署代码(回收应用程序池)来解决问题,或者杀死负载均衡器后面的 1 个坏盒子。有没有人遇到过这个问题?我看到队列中有 9k 项尚未写入出站网络,遵循 azure 故障排除链接:https://azure.microsoft.com/en-us/blog/investigating-timeout-exceptions-in-stackexchange-redis-for-azure-redis-cache/
但是,如果连接没有打开,我特意从我的 redis 数据库工厂抛出一个错误(我在我们的日志中没有看到)。下面是整个类来查看连接多路复用器的初始化:
public class RedisDatabaseFactory : IRedisDatabaseFactory
{
private readonly Lazy<IConnectionMultiplexer> m_lazyConnectionMultiplexer;
public RedisDatabaseFactory(IRedisConfig redisConfig)
{
var endPoint = new DnsEndPoint(redisConfig.Host, redisConfig.Port);
var configOptions = new ConfigurationOptions
{
EndPoints = { endPoint },
Password = redisConfig.Password,
ConnectTimeout = 5000,
AbortOnConnectFail = false
};
m_lazyConnectionMultiplexer = new Lazy<IConnectionMultiplexer>(() =>
ConnectionMultiplexer.Connect(configOptions));
}
private IConnectionMultiplexer Connection
{
get { return m_lazyConnectionMultiplexer.Value; }
}
/// <summary>
/// Gets a connected redis database
/// </summary>
/// <exception cref="Exception"></exception>
/// <returns>Connected redis database</returns>
public IDatabase GetDatabase()
{
if (!Connection.IsConnected)
{
throw new Exception("Redis connection failure");
}
return Connection.GetDatabase();
}
}
这是堆栈跟踪:
System.TimeoutException: Timeout performing SET mykey, inst: 0, mgr: ExecuteSelect, err: never, queue: 9058, qu: 9058, qs: 0, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=1,Free=32766,Min=1,Max=32767), clientName: myclient
at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor1 processor, ServerEndPoint server)
at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor1 processor, ServerEndPoint server)
at StackExchange.Redis.RedisDatabase.StringSet(RedisKey key, RedisValue value, Nullable1 expiry, When when, CommandFlags flags)
at StackExchange.Redis.RedisDatabase.LockTake(RedisKey key, RedisValue value, TimeSpan expiry, CommandFlags flags)
我更改了密钥名称、客户端名称并删除了反引号。
【问题讨论】:
标签: c# redis stackexchange.redis