1

Мы применили наше приложение к Azure. Он использует кэш-память Azure Redis, и мы испытываем довольно много тайм-аутов. А именно:Azure Redis Cache - множественные ошибки TimeoutException: тайм-аут, выполняющий GET {key}

[TimeoutException: Timeout performing GET textobjectDetails__23290_TextObject, inst: 1, mgr: Inactive, queue: 5, qu=0, qs=5, qc=0, wr=0/0, in=56864/0] 

[TimeoutException: Timeout performing GET featured_series_CachedSeries, inst: 1, mgr: Inactive, queue: 4, qu=0, qs=4, qc=0, wr=0/0, in=44470/0] 

[TimeoutException: Timeout performing GET SeriesByFranchiseId_1_CachedSeries, inst: 1, mgr: Inactive, queue: 3, qu=0, qs=3, qc=0, wr=0/0, in=11252/0] 

[TimeoutException: Timeout performing GET media_silo-1-1-0_Media, inst: 1, mgr: Inactive, queue: 3, qu=0, qs=3, qc=0, wr=0/0, in=15188/0] 

[TimeoutException: Timeout performing GET textobjectDetails__3092_TextObject, inst: 3, mgr: Inactive, queue: 7, qu=0, qs=7, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET textobjectbytype_104__TextObject, inst: 11, mgr: Inactive, queue: 9, qu=0, qs=9, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET groupnews_2_14_TextObject, inst: 1, mgr: Inactive, queue: 7, qu=0, qs=7, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET archived_news_by_group_13586_1_TextObject, inst: 2, mgr: Inactive, queue: 7, qu=0, qs=7, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET textobjectDetails__24404_TextObject, inst: 11, mgr: Inactive, queue: 12, qu=0, qs=12, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET standings_232_lcds_fixtures, inst: 2, mgr: Inactive, queue: 11, qu=0, qs=11, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET player_name1099_Player, inst: 4, mgr: Inactive, queue: 11, qu=0, qs=11, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET groupnews_1_6_TextObject, inst: 4, mgr: Inactive, queue: 9, qu=0, qs=9, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET archivednewscount__20789_TextObject, inst: 2, mgr: Inactive, queue: 11, qu=0, qs=11, qc=0, wr=0/0, in=65536/0] 

[TimeoutException: Timeout performing GET media_id3648_Media, inst: 1, mgr: Inactive, queue: 10, qu=0, qs=10, qc=0, wr=0/0, in=65536/0] 

Телом исключения является одинаковым для всех из них:

StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server):509 
    StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor`1 processor, ServerEndPoint server):25 
    StackExchange.Redis.RedisDatabase.StringGet(RedisKey key, CommandFlags flags):16 
    AB.SiteCaching.Providers.RedisDataSource+<>c__DisplayClasse`1.<RetrieveCacheObject>b__b():0 
    Microsoft.Practices.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func):115 
    AB.SiteCaching.Providers.RedisDataSource.RetrieveCacheObject[T](String fullCacheKey):56 
    AB.SiteCaching.Providers.RedisDataSource.RetrieveCached[T](String key, Func`1 onNotCached, TimeSpan timeOut):61 
    DataAccess.Data.Caching.CachedSeries.GetSeriesByFranchiseId(Int32 franchiseId):64 
    Shared.Services.SeriesService.LatestYearByFranchiseId(Int32 franchiseId):0 
    AllBlacksdotcom.Controllers.FixturesController._MostRecentYearOfFixtures(Int32 franchiseId):0 
    (unknown).lambda_method(Closure , ControllerBase , Object[]):-1 
    System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters):0 
    System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters):87 
    System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters):0 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.End():41 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d():20 
    System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f():134 
    System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.End():41 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21+<>c__DisplayClass2b.<BeginInvokeAction>b__1c():0 
    System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult):65 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.End():41 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult):0 
    System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.End():41 
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult):0 
    System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.End():41 
    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult):0 
    System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult):0 
    System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult):0 
    System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1.End():41 
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult):0 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result):0 
    System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper+<>c__DisplayClassa.<EndProcessRequest>b__9():0 
    System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper+<>c__DisplayClass4.<Wrap>b__3():0 
    System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper.Wrap[TResult](Func`1 func):0 
    System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper.Wrap(Action action):25 
    System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper.EndProcessRequest(IAsyncResult result):32 
    System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride):772 

Пожалуйста, смотрите наш тайм-аут настройки:

retryTimeoutInMilliseconds = "5000" 
connectionTimeoutInMilliseconds = "5000" 
operationTimeoutInMilliseconds = "1000" 

Как подойти к этому времени -outs? Будет ли увеличиваться операцияTimeoutInMilliseconds сделать трюк? Я также прочитал, что сжатие g-zip полезно для уменьшения времени, которое требуется для чтения данных из Redis.

Все пакеты nuget, относящиеся к Redis, находятся в их последних версиях. Мы используем C1-версию кеша Azure Redis (увеличиваем до C2-помощи?).

+0

В качестве отправной точки, пожалуйста, вы можете прочитать этот пост и посмотреть, если это помогает http://azure.microsoft.com/blog/2015/02/10/investigating-timeout-exceptions-in- stackexchange-redis-for-azure-redis-cache/ –

+0

@pranavrastogi yep, я посмотрел на него. К сожалению, у меня нет информации Radis от Azure, доступной прямо сейчас, но будет проверяться в понедельник. –

+0

@pranavrastogi Эй, мы проверили пропускную способность, и все было нормально. –

ответ

3

Несколько моментов, которые улучшили ситуацию:

Protobuf-нетто вместо BinaryFormatter

Я рекомендую использовать protobuf-net как это уменьшит размер значений, которые вы хотите хранить в кэше ,

public interface ICacheDataSerializer 
    { 
     byte[] Serialize(object o); 
     T Deserialize<T>(byte[] stream); 
    } 

public class ProtobufNetSerializer : ICacheDataSerializer 
    { 
     public byte[] Serialize(object o) 
     { 
      using (var memoryStream = new MemoryStream()) 
      { 
       Serializer.Serialize(memoryStream, o); 

       return memoryStream.ToArray(); 
      } 
     } 

     public T Deserialize<T>(byte[] stream) 
     { 
      var memoryStream = new MemoryStream(stream); 

      return Serializer.Deserialize<T>(memoryStream); 
     } 
    } 

Реализовать стратегию повтора

Реализовать эту RedisCacheTransientErrorDetectionStrategy для решения вопросов, связанных тайм-аута.

using Microsoft.Practices.TransientFaultHandling; 

public class RedisCacheTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy 
    { 
     /// <summary> 
     /// Custom Redis Transient Error Detenction Strategy must have been implemented to satisfy Redis exceptions. 
     /// </summary> 
     /// <param name="ex"></param> 
     /// <returns></returns> 
     public bool IsTransient(Exception ex) 
     { 
      if (ex == null) return false; 

      if (ex is TimeoutException) return true; 

      if (ex is RedisServerException) return true; 

      if (ex is RedisException) return true; 

      if (ex.InnerException != null) 
      { 
       return IsTransient(ex.InnerException); 
      } 

      return false; 
     } 
    } 

Instantiate так:

private readonly RetryPolicy _retryPolicy; 

// CODE 
var retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(2)); 
      _retryPolicy = new RetryPolicy<RedisCacheTransientErrorDetectionStrategy>(retryStrategy); 

Использование так:

var cachedString = _retryPolicy.ExecuteAction(() => dataCache.StringGet(fullCacheKey)); 

Обзор код минимизировать вызовы кэша и значения, которые вы храните в кэше. Я уменьшил количество ошибок, сохраняя значения более эффективно.

Если это не помогает. Переместитесь в более высокий кеш (мы закончили использование C3 вместо C1).

enter image description here

1

Во всех сообщениях об исключениях у вас есть что-то вроде «in = 65536/0». Это указывает, что 65536 байтов были получены локально (в буфере сокета ядра на локальной машине), но еще не обработаны StackExchange.Redis. Это указывает на проблему на стороне клиентского приложения, которая не позволяет системе обрабатывать ваш ответ. Я могу подумать о двух возможностях, которые могут привести к этому:

  1. В вашей системе недостаточно потоков потоков ниток для быстрой обработки данных. Если вы обновите для сборки 1.0.450 или более поздней версии StackExchange.Redis, сообщения о тайм-ауте будут содержать статистику о том, как занят пул потоков, что поможет диагностировать эту проблему. В качестве альтернативы вы можете использовать код https://github.com/JonCole/SampleCode/blob/master/ThreadPoolMonitor/ThreadPoolLogger.cs, чтобы регистрировать эту же информацию самостоятельно, когда вы получаете исключение.

  2. Вы получаете очень большой объект из кеша, а размер объекта не принимается в течение таймаута, настроенного на StackExchange.Redis. Когда это произойдет, все вызовы, которые были поставлены в очередь на одно и то же соединение за большим элементом, будут таймаутом, когда большой элемент истечет.

В любом случае, надеюсь, что это поможет.

0

Перейдите к Azure и получите экземпляр Redis. Это т

+0

Красивый ответ :)) см. Мой ответ ниже, который говорит все это. –

+0

@JakubHolovsky ваш ответ был отправлен 9:30, ответ автора - 9:25 :) – Nigrimmist

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

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