我们正在使用Redis List来维护我们的C#应用程序要处理的项目队列。该应用程序使用StackExchange.Redis 1.0.488(aka SER)连接到Redis,并通过调用ListRightPushAsync和ListLeftPopAsync SER API来使用列表。
我们主要验证当redis服务器不可用时我们的应用程序将如何表现的场景。
在应用程序忙于处理队列时重新启动Redis服务器后,我们发现了一个问题。在我们看到ListLeftPopAsync占用无限时间且应用程序挂起而没有任何异常的情况下,应用程序恢复处理一定数量的项目。请注意,加载应用程序的处理量高达100000项。下面是代码片段。
消费者层:
public async Task<byte[]> DiscardProcessedItem()
{
var result = await ListLeftPopAsync(2, "2:l:queue1");
return result;
}
SER API Wrapper:
public Task<byte[]> ListLeftPopAsync(int redisDb, string key)
{
var task = conn.GetDatabase(redisDb).ListLeftPopAsync(key);
return Task.FromResult<byte[]>(task.Result);
}
请注意,syncTimeout为5000。
然后我们尝试通过修改包装函数来使用同步SER API,如下所示
public byte[] ListLeftPopAsync(int redisDb, string key)
{
return conn.GetDatabase(redisDb).ListLeftPop(key);
}
此更改后,应用程序未挂起并处理整个队列。但是,对于少数项目执行ListLeftPop时,StackExchange.Redis会抛出超时异常。例外情况粘贴在下面。
超时执行LPOP 2:l:queue1,inst:1,mgr:ProcessReadQueue,err:never,queue:6,qu:0,qs:6,qc:0,wr:0,wq:0,in: 260,ar:1,IOCP :( Busy = 0,Free = 1000,Min = 4,Max = 1000),WORKER :( Busy = 0,Free = 2047,Min = 4,Max = 2047),clientName:MYPC < / p>
任何线索都会非常感激。
答案 0 :(得分:0)
增加同步超时或使用堆栈交换库提供的一些异步机制。
ConfigurationOptions co = new ConfigurationOptions()
{
SyncTimeout = 500000,
EndPoints =
{
{url,portNumber }
},
AbortOnConnectFail = false // this prevents that error
};
seClient = ConnectionMultiplexer.Connect(co);
当您使用旧版本的客户端
时,也可能会发生这种情况