Ответ 1
Короче говоря, нет.
Время, затрачиваемое кластером на перезагрузку, увеличивается при добавлении дополнительных узлов, что заставляет меня думать, что это процесс синхронизации node, который занимает время.
Исключением, которое вы видите, действительно является приложением node, входящим в дроссельное состояние. Он войдет в дроссельное состояние, в зависимости от того, как у вас установлены водяные знаки с высоким/низким значением на node. Я думаю, что по умолчанию показатель высокой воды составляет 90%, после этого он начнет высекать элементы, определяющие политику выселения, установленную в кеше. Обычно вы должны использовать LRU (совсем недавно), но если кеш все еще не может работать в пределах установленных ограничений, он будет дросселировать себя, чтобы не довести ваш сервер.
Ваше приложение принесет пользу, если оно сможет обработать такие события изящно. Если у вас есть все узлы, перечисленные в конфигурации кластера вашего приложения, ваше приложение должно перейти к следующему node при следующей попытке получить данные. Мы используем цикл повтора, который ищет временный сбой и повторяет попытку 3 раза. Если после 3-х ошибок ошибка сохраняется, мы регистрируем и возвращаем значение null, а не exeption. Это позволяет приложению пытаться получить доступ к другому node или разрешить проблему node для восстановления:
private object WithRetry(Func<object> method)
{
int tryCount = 0;
bool done = false;
object result = null;
do
{
try
{
result = method();
done = true;
}
catch (DataCacheException ex)
{
if (ex.ErrorCode == DataCacheErrorCode.KeyDoesNotExist)
{
done = true;
}
else if ((ex.ErrorCode == DataCacheErrorCode.Timeout ||
ex.ErrorCode == DataCacheErrorCode.RetryLater ||
ex.ErrorCode == DataCacheErrorCode.ConnectionTerminated)
&& tryCount < MaxTryCount)
{
tryCount++;
LogRetryException(ex, tryCount);
}
else
{
LogException(ex);
done = true;
}
}
}
while (!done);
return result;
}
И это позволяет нам сделать следующее:
private void AF_Put(string key, object value)
{
WithRetry(() => defaultCache.Put(key, value));
}
или
private object AF_Get(string key)
{
return WithRetry(() => defaultCache.Get(key));
}