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中!就我而言,它被隱藏在一個輔助方法中,我不得不挖掘一下才能找到它。