Caché de Azure Redis: tiempos de espera en llamadas GET

Tenemos varios roles web y de trabajo en Azure que se conectan a nuestra memoria caché de Azure Redis a través de la biblioteca StackExchange.Redis, y estamos recibiendo tiempos de espera regulares que están haciendo que nuestra solución de extremo a extremo se detenga. Un ejemplo de uno de ellos está a continuación:

System.TimeoutException: Timeout realizando GET stream: 459, inst: 4, mgr: Inactivo, cola: 12, qu = 0, qs = 12, qc = 0, wr = 0/0, in = 65536/0 en StackExchange.Redis .ConnectionMultiplexer.ExecuteSyncImpl [T] (Mensaje de mensaje, ResultProcessor1 processor, ServerEndPoint server) in c:\TeamCity\buildAgent\work\58bc9a6df18a3782\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:line 1785 at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor1 procesador, servidor ServerEndPoint) en c: \ TeamCity \ buildAgent \ work \ 58bc9a6df18a3782 \ StackExchange.Redis \ StackExchange \ Redis \ RedisBase.cs: línea 79 en StackExchange.Redis.RedisDatabase.StringGet (RedisKey key, CommandFlags flags) en c: \ TeamCity \ buildAgent \ work \ 58bc9a6df18a3782 \ StackExchange.Redis \ StackExchange \ Redis \ RedisDatabase.cs: línea 1346 en OptiRTC.Cache.RedisCacheActions. <> C__DisplayClass41.<Get>b__3() in c:\dev\OptiRTCAzure\OptiRTC.Cache\RedisCacheActions.cs:line 104 at Polly.Retry.RetryPolicy.Implementation(Action action, IEnumerable1 shouldRetryPredicates, Func`1 policyStateFactory) en OptiRTC.Cache.RedisCacheActions.Get [T] (String key, Boolean allowDirtyRead) en c: \ dev \ OptiRTCAzure \ OptiRTC.Cache \ RedisCacheActions.cs: line 107 en OptiRedisCache.checcess.Cache .d__e4.MoveNext () en c: \ dev \ OptiRTCAzure \ OptiRTC.Cache \ RedisCacheAccess.cs: línea 1196; Evento TraceSource 'WaWorkerHost.exe'

Todos los tiempos de espera tienen diferentes números de cola y qs, pero el resto de los mensajes son consistentes. Estas llamadas StringGet se realizan en diferentes claves en la memoria caché. En cada uno de nuestros servicios, utilizamos una clase de acceso de caché singleton con un único ConnectionMultiplexer que está registrado con nuestro contenedor de IoC en el inicio de la función web o trabajador:

        container.RegisterInstance<ICacheAccess>(cacheAccess);

En nuestra implementación de ICacheAccess, estamos creando el multiplexor de la siguiente manera:

            ConfigurationOptions options = new ConfigurationOptions();
            options.EndPoints.Add(serverAddress);
            options.Ssl = true;
            options.Password = accessKey;                    
            options.ConnectTimeout = 1000;
            options.SyncTimeout = 2500;

            redis = ConnectionMultiplexer.Connect(options);

donde se usa el objeto redis en toda la instancia. Tenemos alrededor de 20 instancias de roles web y de trabajo que se conectan al caché a través de esta implementación de ICacheAccess, pero la consola de administración muestra un promedio de 200 conexiones simultáneas al caché.

He visto otras publicaciones que hacen referencia usando la versión 1.0.333 de StackExchange.Redis, lo que estamos haciendo a través de NuGet, pero cuando miro la versión real de la referencia StackExchange.Redis.dll agregada, muestra 1.0.316.0. Intentamos agregar y eliminar la referencia NuGet, así como agregarla a un nuevo proyecto, y siempre obtenemos la discrepancia de versión.

Cualquier idea sería apreciada. Gracias.

Información Adicional:

Hemos actualizado a 1.0.371. Tenemos dos servicios que acceden al mismo objeto de caché a diferentes intervalos, uno para editar y leer ocasionalmente y otro que lee este objeto varias veces por segundo. Ambos servicios se implementan con el mismo código de almacenamiento en caché y la versión de la biblioteca StackExchange.Redis. Casi nunca veo tiempos de espera en el servicio que edita el objeto, pero obtengo tiempos de espera entre el 50 y el 75% del tiempo en los servicios que lo leen. Los tiempos de espera tienen el mismo formato que el indicado anteriormente, y continúan ocurriendo después de ajustar la llamada db.StringGet en un bloque de reintento de Polly que maneja tanto RedisException como System.TimeoutException y reintenta una vez después de 500ms.

Contactamos a Microsoft sobre este problema, y confirman que no ven nada en los registros de Redis que indiquen un problema en el lado del servicio de Redis. Nuestro% de pérdida de caché es extremadamente bajo en el servidor Redis, pero continuamos obteniendo estos tiempos de espera, lo que dificulta sustancialmente la funcionalidad de nuestra aplicación.

En respuesta a los comentarios, sí, siempre tenemos un número en qs y nunca en qc. Siempre tenemos un número en la primera parte de la entrada y nunca en la segunda.

Aún más información adicional:

Cuando ejecuto un servicio con menos instancias en una CPU más alta, obtengo significativamente más de estos errores de tiempo de espera que cuando las instancias se ejecutan en CPU más bajas. Más específicamente, saqué algunos números de nuestros servicios esta mañana. Cuando funcionaban con alrededor del 30% de CPU, vi muy pocos problemas de tiempo de espera, solo 42 en 30 minutos. Cuando eliminé la mitad de las instancias y comenzaron a funcionar con una CPU de alrededor del 60-65%, la tasa aumentó 10 veces a 536 en 30 minutos.

Respuestas a la pregunta(2)

Su respuesta a la pregunta