servicestack.redis,Multithreading,Redis,Quartz.net,Sortedset,servicestack.redis" /> servicestack.redis,Multithreading,Redis,Quartz.net,Sortedset,servicestack.redis" />

Multithreading RedisResponseException:对多个请求的答复未知

Multithreading RedisResponseException:对多个请求的答复未知,multithreading,redis,quartz.net,sortedset,servicestack.redis,Multithreading,Redis,Quartz.net,Sortedset,servicestack.redis,我们有一个windows服务,每分钟运行一次quartz作业,以处理3个多小时前提交的评论。应用程序使用最新的ServiceStack.Redis v3库与另一台计算机上的Redis 2.8.12实例进行接口 提交新评论时,新评论的ID存储在Redis中的一个排序集中,我们使用NewReview.DateCreated.Ticks作为分数。当作业运行时,它执行以下代码以获取要处理的审阅列表: using (var redisClient = RedisClientManager.GetClien

我们有一个windows服务,每分钟运行一次quartz作业,以处理3个多小时前提交的评论。应用程序使用最新的ServiceStack.Redis v3库与另一台计算机上的Redis 2.8.12实例进行接口

提交新评论时,新评论的ID存储在Redis中的一个排序集中,我们使用NewReview.DateCreated.Ticks作为分数。当作业运行时,它执行以下代码以获取要处理的审阅列表:

using (var redisClient = RedisClientManager.GetClient())
{
    ...
    var cutOff = DateTime.Now.AddHours(-3);
    redisClient.GetRangeFromSortedSetByLowestScore("pending_reviews", 0L, cutOff);
    ...
}
通常情况下,这可以正常工作,如果排序集中有任何3小时或3小时以上的评论,则会返回它们的ID,并且作业会正常处理它们。但是,相同的确切代码会间歇性地导致以下异常:

ServiceStack.Redis.RedisResponseException: Unknown reply on multi-request: ...
at ServiceStack.Redis.RedisNativeClient.CreateResponseError(String error)
at ServiceStack.Redis.RedisNativeClient.ReadMultiData()
at ServiceStack.Redis.RedisNativeClient.SendExpectMultiData(Byte[][] cmdWithBinaryArgs)
at ServiceStack.Redis.RedisNativeClient.GetRangeByScore(Byte[] commandBytes, String setId, Int64 min, Int64 max, Nullable`1 skip, Nullable`1 take, Boolean withScores)
at ServiceStack.Redis.RedisNativeClient.ZRangeByScore(String setId, Int64 min, Int64 max, Nullable`1 skip, Nullable`1 take)
at ServiceStack.Redis.RedisClient.GetRangeFromSortedSetByLowestScore(String setId, Int64 fromScore, Int64 toScore, Nullable`1 skip, Nullable`1 take)
at ServiceStack.Redis.RedisClient.GetRangeFromSortedSetByLowestScore(String setId, Int64 fromScore, Int64 toScore)
我尝试下载并进入ServiceStack源代码,但在调试时问题从未发生过,我似乎无法以其他方式复制它。RedisClientManager是一个单池RedisClientManager,据我所知,我正在正确创建和处理客户机,并且我也没有使用事务或管道

我的理解是,池客户端管理器正在做一些棘手的连接共享工作,因为Redis实际上是单线程的。感觉它可能从另一个连接或其他线程或连接共享问题返回了错误的结果

你知道是什么导致了这一切吗

好吧,我想出来了

稍后在作业中,在检索ID之后,它实际上使用了一个事务。当我更仔细地查看事务代码时,我意识到在单个QueueCommand的上下文中进行了多个客户端调用。虽然在初始作业调用期间没有发生错误,但在下一次作业运行时,它始终会收到错误

所以我简单地将每个客户端调用分解成它自己的QueueCommand,瞧,错误消失了。经验教训:当使用事务/管道时,要非常小心,每个redis客户端调用都在它自己的专用队列命令中!在我的例子中,它隐藏在一个helper方法中,我必须挖掘一点才能找到它