Устранение проблем масштабирования AppFabric (прерывистый код ошибки <ERRCA0017>: SubStatus <ES0006> Ошибки)

Мы применили кэш веб-приложений AppFabric для Windows. Первоначально мы могли использовать кеш без каких-либо проблем. Затем мы увеличили трафик примерно в 100 раз и начали испытывать прерывистые исключения. Исключения происходят примерно один раз в 2 дня, в течение примерно одной минуты за раз.

Наша конфигурация:

  • 9 веб-серверов вставки/извлечения объектов в кеш:
    • В основном временные 500-байтовые операционные типы объектов
    • Использование 1 названной области
    • Объекты, хранящиеся с тегами
    • Получено навалом для данного тега
  • Кэш-кластер:
    • 1 хост (ведущий) AppFabric 1.1 (версия, указанная get-cachehost, равна 3)
    • Поставщик конфигурации SQL
    • 96 ГБ оперативной памяти на хосте, по умолчанию 50% (48 ГБ) выделено AppFabric
    • Cache Host Конфигурация
    • Клиент кэша Конфигурация

Ошибки в порядке их возникновения (исключения происходят для каждого из девяти веб-серверов в течение 1-минутного периода):

  • System.Net.Sockets.SocketException: существующее соединение было принудительно закрыто удаленным хостом Microsoft.ApplicationServer.Caching.DataCacheException: ErrorCode<ERRCA0016>:SubStatus<ES0001>:The connection was terminated, possibly due to server or network problems or serialized Object size is greater than MaxBufferSize on server. Result of the request is unknown. ---> System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:15:00'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host --- End of inner exception stack trace --- at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Channels.FramingDuplexSessionChannel.EndReceive(IAsyncResult result) at Microsoft.ApplicationServer.Caching.WcfClientChannel.CompleteProcessing(IAsyncResult result) --- End of inner exception stack trace --- at Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ResponseBody respBody) at Microsoft.ApplicationServer.Caching.DataCache.GetNextBatch(String region, DataCacheTag[] tags, GetByTagsOperation op, IMonitoringListener listener, Byte[][]& state, Boolean& more) at Microsoft.ApplicationServer.Caching.CacheEnumerator.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator'2.MoveNext() at System.Linq.Enumerable.<ExceptIterator>d__99'1.MoveNext() at System.Collections.Generic.List'1..ctor(IEnumerable'1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable'1 source)

  • Microsoft.ApplicationServer.Caching.DataCacheException: ErrorCode<ERRCA0017>:SubStatus<ES0006>:There is a temporary failure. Please retry later. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. For on-premises cache clusters, also verify the following conditions. Ensure that security permission has been granted for this client account, and check that the AppFabric Caching Service is allowed through the firewall on all cache hosts. Also the MaxBufferSize on the server must be greater than or equal to the serialized object size sent from the client.) at Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ResponseBody respBody) at Microsoft.ApplicationServer.Caching.DataCache.GetNextBatch(String region, DataCacheTag[] tags, GetByTagsOperation op, IMonitoringListener listener, Byte[][]& state, Boolean& more) at Microsoft.ApplicationServer.Caching.CacheEnumerator.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator'2.MoveNext() at System.Linq.Enumerable.<ExceptIterator>d__99'1.MoveNext() at System.Collections.Generic.List'1..ctor(IEnumerable'1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable'1 source)

  • Microsoft.ApplicationServer.Caching.DataCacheException: ErrorCode<ERRCA0018>:SubStatus<ES0001>:The request timed out. at Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ResponseBody respBody) at Microsoft.ApplicationServer.Caching.DataCache.GetNextBatch(String region, DataCacheTag[] tags, GetByTagsOperation op, IMonitoringListener listener, Byte[][]& state, Boolean& more) at Microsoft.ApplicationServer.Caching.CacheEnumerator.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator'2.MoveNext() at System.Linq.Enumerable.<ExceptIterator>d__99'1.MoveNext() at System.Collections.Generic.List'1..ctor(IEnumerable'1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable'1 source)

Мы также создали сеанс tracelog на сервере кеширования для сбора дополнительной информации для диагностики проблемы - любые предложения по анализу этого будут оценены (я могу сделать это доступным, если потребуется).

Мы также отслеживали различные счетчики производительности AppFabric, CLR и Network, ниже приведен снимок экрана, как это происходит:

AppFabric Perfmon Capture

Заранее благодарим за любые мысли или советы, которые вы можете поделиться при решении этой проблемы.

ОБНОВЛЕНИЕ 1

Ниже перечислены исключения, происходящие непрерывно в кэшировании AppFabric Server во время прерывистых ошибок (абстрагированных от tracelogs):

  • System.ServiceModel.CommunicationException: The socket connection was aborted because an asynchronous send to the socket did not complete within the allotted timeout of 00:00:00.0082078. The time allotted to this operation may have been a portion of a longer timeout. ---> System.ObjectDisposedException: The socket connection has been disposed. Object name: 'System.ServiceModel.Channels.SocketConnection'. --- End of inner exception stack trace --- at System.ServiceModel.Channels.SocketConnection.ThrowIfNotOpen() at System.ServiceModel.Channels.SocketConnection.BeginRead(Int32 offset, Int32 size, TimeSpan timeout, WaitCallback callback, Object state) at System.ServiceModel.Channels.SessionConnectionReader.BeginReceive(TimeSpan timeout, WaitCallback callback, Object state) at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.PerformOperation(TimeSpan timeout) at System.ServiceModel.Channels.SynchronizedMessageSource.SynchronizedAsyncResult'1..ctor(SynchronizedMessageSource syncSource, TimeSpan timeout, AsyncCallback callback, Object state) at System.ServiceModel.Channels.FramingDuplexSessionChannel.BeginReceive(TimeSpan timeout, AsyncCallback callback, Object state) at Microsoft.ApplicationServer.Caching.WcfServerChannel.CompleteProcessing(IAsyncResult result)

  • System.ServiceModel.CommunicationObjectAbortedException: The communication object, System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel, cannot be used for communication because it has been Aborted. at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Channels.FramingDuplexSessionChannel.OnEndSend(IAsyncResult result) at Microsoft.ApplicationServer.Caching.ReplyContext.EndSend(IAsyncResult result)

  • System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel, cannot be used for communication because it is in the Faulted state. at System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen() at System.ServiceModel.Channels.OutputChannel.Send(Message message, TimeSpan timeout) at Microsoft.ApplicationServer.Caching.ReplyContext.Reply(Message message, TimeSpan timeout)

  • System.TimeoutException: Sending to via http://www.w3.org/2005/08/addressing/anonymous timed out after 00:00:15. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: Cannot claim lock within the allotted timeout of 00:00:15. The time allotted to this operation may have been a portion of a longer timeout. --- End of inner exception stack trace --- at System.ServiceModel.Channels.FramingDuplexSessionChannel.OnSend(Message message, TimeSpan timeout) at System.ServiceModel.Channels.OutputChannel.Send(Message message, TimeSpan timeout) at Microsoft.ApplicationServer.Caching.ReplyContext.Reply(Message message, TimeSpan timeout)

ОБНОВЛЕНИЕ 2

После еще одного дня устранения неполадок мы предприняли следующие действия, которые привели к некоторым улучшениям:

  • На основе this и this мы увеличили maxConnectionsToServer до 3. В результате мы получили на 50% больше клиентских запросов/сек, записанных с помощью AppFabric Caching: Cache perf, но прерывистые ошибки не прекращались

  • Мы увеличили maxBufferSize и maxBufferPoolSize до 2147483647 (int32.max) в конфигурации Cache Server. Пока мы можем обрабатывать 300-кратный объем трафика без ошибок. Мы продолжим увеличивать объем трафика и отслеживать. Дополнительные обновления для

ОБНОВЛЕНИЕ 3

Мы добавили еще два хоста с 16 ГБ в кластер и включили режим HighAvailability (через Secondaries=1). В настоящее время исходный хост остается в кластере с 96 ГБ оперативной памяти - все хосты имеют cacheSize = 12 GB. На клиентах кеша мы увеличиваем значение MaxConnectionToServer до 12 (1 на ядро). Ниже приведены наши выводы:

  • Иногда мы получаем (один или два раза каждые 10 минут):
    • ErrorCode<ERRCA0017>:SubStatus<ES0005>:There is a temporary failure. Please retry later. (There was a contention on the store.)
    • ErrorCode<ERRCA0017>:SubStatus<ES0004>:There is a temporary failure. Please retry later. (Replication queue was full. This may happen during reconfiguration of cluster hosts.)
  • Исходные 96-гигабайтные серверы кэша по-прежнему испытывают 1 минус отключения, как описано выше. Новые хосты кэша не испытывали сбоя

Мы планируем удалить 80 ГБ оперативной памяти из исходного хоста. Дополнительные обновления.

ОБНОВЛЕНИЕ 4

Проблема, похоже, была решена путем уменьшения объема ОЗУ в узлах кэша до 16 ГБ. Мы больше не видим прерывистых ошибок при увеличении трафика до 400 раз. Кажется, что он закрыт. Теперь к следующему вопросу: Высокая доступность

Ответы

Ответ 1

Отмена ответа, полученного Jeff-ITGuy на social.msdn.microsoft.com:

Вы сталкиваетесь с проблемой, почти идентичной той, с которой я сейчас работаю с Microsoft. Если это та же проблема, это, вероятно, вызвано тем, что GC занимает много времени и вызывает задержки в времени отклика для AppFabric. Начиная с ваших счетчиков, это выглядело так, что время GC запустилось, когда вы начали получать проблему, поэтому, вероятно, это та же проблема.

Эта проблема активно исследуется Microsoft. Тем временем, чтобы облегчить проблему (по крайней мере, из наших выводов), вы можете запускать больше серверов с меньшим объемом памяти (уменьшить размер пространства памяти, с которым работает GC), и вы можете увеличить RequestTimeout на своем клиенте. По умолчанию установлено значение 15000 (15 секунд), но мы попытались повысить его до 30000, что помогло устранить некоторые проблемы. На мой взгляд, это не очень хорошее долгосрочное решение, просто передавая информацию. Я видел проблему с серверами, имеющими только 24-гигабайтную память (с 12 гб для кеша), и она действительно только заметно улучшилась, когда мы попробовали серверы с 8 ГБ с 4 КБ в кеш-кеш, что заставило GC сделать БОЛЬШЕ лучше.

Надеюсь, что это поможет, но если это проблема, я думаю, что пока нет решения.

Это помогло, прерывистые ошибки прекратились после того, как мы сократили RAM-память кэша до 16 ГБ.

Ответ 2

  • Установили ли вы http://support.microsoft.com/kb/983182 и http://support.microsoft.com/kb/2527387?
  • В вашем коде вы проверяете исключение и retrolater bool?

                    catch (DataCacheException ex2)
                {
                    if (ex2.ErrorCode == DataCacheErrorCode.RetryLater)
                    {
    

    Использование именованной области заставляет сервер вытолкнуть значения этой области имени на один сервер, а не распространять хэши на всех ваших серверах кеша. ( "Чтобы обеспечить эту добавленную функциональность поиска, объекты в регионе ограничены одним узлом кеша". http://msdn.microsoft.com/en-us/library/ee790985(v=azure.10).aspx)

Я бы порекомендовал, что вы очертите свою именованную область на еще 2 серверах и поместите их в кластер. Таким образом, вы ограничиваете исключения на меньшем сервере, когда он запускает GC, и пытается найти больше бара, чтобы помещать и хранить объекты и теги.