У меня есть следующие проблемы в нашей производственной среде (веб-ферма - 4 узла, поверх нее Load balancer):
1) Timeout performing HGET key, inst: 3, queue: 29, qu=0, qs=29, qc=0, wr=0/0
at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor``1 processor, ServerEndPoint server) in ConnectionMultiplexer.cs:line 1699
Это происходит 3-10 раз в минуту
2) No connection is available to service this operation: HGET key at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor``1 processor, ServerEndPoint server) in ConnectionMultiplexer.cs:line 1666
Я попытался реализовать, как предположил Марк (возможно, я интерпретировал его неправильно) - лучше иметь меньше соединений с Redis, чем несколько. Я выполнил следующую реализацию:
public class SeRedisConnection
{
private static ConnectionMultiplexer _redis;
private static readonly object SyncLock = new object();
public static IDatabase GetDatabase()
{
if (_redis == null || !_redis.IsConnected || !_redis.GetDatabase().IsConnected(default(RedisKey)))
{
lock (SyncLock)
{
try
{
var configurationOptions = new ConfigurationOptions
{
AbortOnConnectFail = false
};
configurationOptions.EndPoints.Add(new DnsEndPoint(ConfigurationHelper.CacheServerHost,
ConfigurationHelper.CacheServerHostPort));
_redis = ConnectionMultiplexer.Connect(configurationOptions);
}
catch (Exception ex)
{
IoC.Container.Resolve<IErrorLog>().Error(ex);
return null;
}
}
}
return _redis.GetDatabase();
}
public static void Dispose()
{
_redis.Dispose();
}
}
На самом деле утилизация не используется прямо сейчас. Также у меня есть некоторые особенности реализации, которые могут вызвать такое поведение (я использую только хеши): 1. Добавить, Удалить хэши - асинхронный 2. Получить -sync
Может ли кто-нибудь помочь мне, как избежать такого поведения?
Большое спасибо!
SOLVED - увеличение тайм-аута подключения клиента после оценки сетевых возможностей.
ОБНОВЛЕНИЕ 2: На самом деле это не решило проблему. Когда объем кеша начинает увеличиваться, например, от 2GB. Затем я увидел тот же шаблон, на самом деле эти таймауты случались каждые 5 минут. И наши сайты были заморожены в течение некоторого периода времени каждые 5 минут, пока работа вилки не была закончена. Затем я узнал, что есть возможность сделать вилку (сохранить на диск) каждые x секунд:
save 900 1
save 300 10
save 60 10000
В моем случае это было "save 300 10" - сэкономьте каждые 5 минут, если произошло не менее 10 обновлений. Также я узнал, что "вилка" может быть очень дорогой. Прокомментированный раздел "Сохранить" разрешил проблему вообще. Мы можем прокомментировать раздел "сохранить", поскольку мы используем только Redis как "кеш в памяти" - нам не нужно никакого сопротивления. Вот конфигурация нашего сервера кеш-серверов "Redis 2.4.6": https://github.com/rgl/redis/downloads
Возможно, он был решен в последних версиях оконных окон Redis в MSOpentech: http://msopentech.com/blog/2013/04/22/redis-on-windows-stable-and-reliable/ но я еще не тестировал.
В любом случае StackExchange.Redis не имеет ничего общего с этой проблемой, и он работает довольно стабильно в нашей производственной среде благодаря Marc Gravell.
ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ: Redis - однопоточное решение - это в конечном счете быстро, но когда дело доходит до освобождения памяти (удаление элементов, которые устарели или истекли), проблемы возникают из-за одного потока, чтобы вернуть память (что не является быстрой операцией - любой алгоритм используется), и тот же поток должен обрабатывать операции GET, SET. Конечно, это происходит, когда мы говорим о среднесрочной рабочей среде. Даже если вы используете кластер с ведомыми устройствами при достижении барьера памяти, он будет иметь такое же поведение.