Подтвердить что ты не робот

StackExchange.Redis timeout и "Нет подключения для обслуживания этой операции"

У меня есть следующие проблемы в нашей производственной среде (веб-ферма - 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. Конечно, это происходит, когда мы говорим о среднесрочной рабочей среде. Даже если вы используете кластер с ведомыми устройствами при достижении барьера памяти, он будет иметь такое же поведение.

4b9b3361

Ответ 1

Похоже, что в большинстве случаев это исключение является проблемой клиента. Предыдущие версии StackExchange.Redis использовали Win32-сокет напрямую, что иногда оказывает негативное влияние. Вероятно, внутренняя маршрутизация Asp.net как-то связана с этим.
Хорошей новостью является то, что инфраструктура сети StackExchange.Redis была недавно полностью переписана. Последняя версия 2.0.513. Попробуйте, и есть большая вероятность, что ваша проблема исчезнет.