0

У нас есть служба Windows, которая каждую минуту выполняет кварцевое задание для обработки отзывов, которые были отправлены более 3 часов назад. Приложение использует последнюю библиотеку ServiceStack.Redis v3 для взаимодействия с экземпляром Redis 2.8.12 на другом компьютере.RedisResponseException: Неизвестный ответ по многопользовательскому запросу

Когда новый обзор отправлен, идентификатор нового обзора хранится в отсортированном наборе в Redis, и мы используем NewReview.DateCreated.Ticks для оценки. При выполнении задания, он выполняет следующий код, чтобы получить список обзоров, подлежащих обработке:

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

Обычно, это работает отлично, и если есть какие-либо отзывы в отсортированный набор 3 часа и старше их Идентификаторы возвращаются, и задание обрабатывает их нормально. Однако точно такой же код будет периодически вызывать происходить следующее исключение:

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 - это singleton PooledRedisClientManager, и насколько я могу судить, я правильно создаю и удаляю клиента, и я тоже не использую транзакцию или конвейер.

Мое понимание заключается в том, что объединенный клиентский менеджер делает некоторые сложные связи, поскольку Redis фактически однопоточен. Похоже, что он может возвращать неправильные результаты из другого соединения или какой-либо другой проблемы с потоком или совместным подключением.

Любые идеи о том, что может быть причиной этого?

ответ

0

Хорошо, я понял.

Позже, после того, как идентификаторы были восстановлены, на самом деле была использована транзакция. Когда я более внимательно рассмотрел код транзакции, я понял, что несколько клиентских вызовов выполняются в контексте одного QueueCommand. Несмотря на то, что во время первоначального вызова работы не было ошибок, в следующий раз, когда работа выполнялась, всегда будет возникать ошибка.

Так что я просто разбил каждый клиентский вызов на свой собственный QueueCommand и Voila, ошибка исчезла. Извлеченный урок: при использовании транзакций/трубопроводов будьте очень осторожны, чтобы каждый клиентский вызов redis находился в собственной выделенной QueueCommand! В моем случае это было скрыто в вспомогательном методе, и мне пришлось немного подражать, чтобы найти его.

 Смежные вопросы

  • Нет связанных вопросов^_^