0

我们有一个windows服务,每分钟运行一次石英工作来处理3小时前提交的评论。该应用程序使用最新的ServiceStack.Redis v3库与另一台机器上的Redis 2.8.12实例进行交互。RedisResponseException:多请求中的未知答复

当提交新评论时,新评论的ID将存储在Redis的已排序集中,我们正在使用NewReview.DateCreated.Ticks获得评分。当作业运行时,它执行下面的代码,以获得评价的列表进行处理:

using (var redisClient = RedisClientManager.GetClient()) 
{ 
    ... 
    var cutOff = DateTime.Now.AddHours(-3); 
    redisClient.GetRangeFromSortedSetByLowestScore("pending_reviews", 0L, cutOff); 
    ... 
} 

通常情况下,这工作得很好,如果有在分类设置过去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是一个单身PooledRedisClientManager,据我可以告诉我正在创建和处理客户端,我也没有使用事务或管道。

我的理解是,由于Redis实际上是单线程的,所以合并的客户端管理器正在做一些棘手的连接共享。感觉就像它可能从另一个连接或其他线程或连接共享问题返回错误的结果。

关于可能导致此问题的任何想法?

回答

0

好的我想通了。

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

因此,我只是把每个客户端调用到它自己的QueueCommand和Voila中,错误消失了。获得的经验:使用事务/管道时要非常小心,每个redis客户端调用都在它自己的专用QueueCommand中!就我而言,它被隐藏在一个辅助方法中,我不得不挖掘一下才能找到它。