2010-09-24 12 views
33

Estoy buscando la forma más eficaz de organizar el uso de la caché de datos y la fábrica de caché de datos para las llamadas de caché de AppFabric, para obtener entre 400 y 700 caché por carga de página (y apenas cualquier puts) . Parece que usar una única DataCacheFactory estática (o posiblemente una pareja en una configuración round-robin) es el camino a seguir.Caché de AppFabric: uso adecuado de DataCacheFactory y DataCache

¿Llamo a GetCache ("cacheName") para cada solicitud de objeto DataCache, o hago una estática en el momento en que se inicia la fábrica de DataCache y la utilizo para todas las llamadas?

¿Tengo que manejar excepciones, verificar los códigos de error e intentar reintentos?

¿Tengo que considerar contención cuando más de un subproceso intenta usar el almacén de memoria caché y quiere el mismo elemento (por clave)?

¿Existe algún tipo de documentación que explora adecuadamente el diseño y el uso de esto?


Parte de la información que he reunido hasta el momento a partir del foro:

http://social.msdn.microsoft.com/Forums/en-AU/velocity/thread/98d4f00d-3a1b-4d7c-88ba-384d3d5da915

"Creación de la fábrica consiste en conectar al clúster y puede tomar algún tiempo, pero una vez que usted. tener el objeto de fábrica y la memoria caché con la que desea trabajar, simplemente puede reutilizar esos objetos para hacer puestas y acceder al caché, y debería ver un rendimiento mucho más rápido ".

http://social.msdn.microsoft.com/Forums/en-US/velocity/thread/0c1d7ce2-4c1b-4c63-b525-5d8f98bb8a49

"Creación DataCacheFactory sola (Singleton) es más rendimiento que la creación de múltiples DataCacheFactory. No debe crear DataCacheFactory para cada llamada, tendrá impacto en el rendimiento."

"Intente encapsular el algoritmo round-robin (teniendo 3/4/5 instancias de fábrica) en su singleton y compare los resultados de la prueba de carga".

http://blogs.msdn.com/b/velocity/archive/2009/04/15/pushing-client-performance.aspx

"se puede aumentar el número de clientes para aumentar el rendimiento de la memoria caché. Pero a veces, si usted quiere tener conjunto más pequeño de clientes y aumentar el rendimiento, un truco es utilizar varias instancias DataCacheFactory. La instancia DataCacheFactory crea una conexión a los servidores (por ejemplo, si hay 3 servidores, creará 3 conexiones) y multiplexa todas las solicitudes de las cadenas de datos en estas conexiones. Por lo tanto, si el volumen de envío/recepción es muy alto, estas conexiones TCP podrían Por lo tanto, una forma es crear múltiples instancias de DataCacheFactory y luego usar las operaciones en ellas ".


Aquí lo que está en uso hasta ahora ... se llama a la propiedad y si el valor de retorno no es nulo se realiza una operación.

private static DataCache Cache 
{ 
    get 
    { 
     if (_cacheFactory == null) 
     { 
      lock (Sync) 
      { 
       if (_cacheFactory == null) 
       { 
        try 
        { 
         _cacheFactory = new DataCacheFactory(); 
        } 
        catch (DataCacheException ex) 
        { 
         if (_logger != null) 
         { 
          _logger.LogError(ex.Message, ex); 
         } 
        } 
       } 
      } 
     } 

     DataCache cache = null; 

     if (_cacheFactory != null) 
     { 
      cache = _cacheFactory.GetCache(_cacheName); 
     } 

     return cache; 
    } 
} 

Ver esta pregunta en el foro de Microsoft AppFabric: http://social.msdn.microsoft.com/Forums/en-AU/velocity/thread/e0a0c6fb-df4e-499f-a023-ba16afb6614f

+0

Hay una respuesta a esta ahora en el foro. Verifique el enlace de arriba. – CRice

Respuesta

15

Aquí está la respuesta del mensaje del foro:

Hola. Perdón por la respuesta tardía, pero quiero decir que estas son preguntas geniales y probablemente sean útiles a otras.

No debería haber una necesidad de más de un DataCacheFactory por hilo a menos que se requieren diferentes configuraciones . Por ejemplo, si se configura el programación DataCacheFactory con la clase DataCacheFactoryConfiguration, entonces puede que desee crear uno que tiene caché local habilitado y otra que no lo hace. En este caso, usted usaría diferentes objetos DataCacheFactory según la configuración que requiera para su escenario. Pero otras que las diferencias en la configuración, usted no debería ver una ganancia de rendimiento en creando múltiples DataCacheFactories.

sobre el mismo tema, hay un ajuste MaxConnectionsToServer (ya sea programática en DataCacheFactoryConfiguration o en el archivo de configuración de la aplicación como un atributo del elemento dataCacheClient ).Esto determina el número de chennels por DataCacheFactory que están abiertos en el clúster de caché. Si tiene tiene requisitos de alto rendimiento y también disponible CPU/red ancho de banda, aumentar este ajuste a 3 o superior puede aumentar el rendimiento. No recomendamos aumentar sin causa o un valor que es demasiado alto para sus necesidades. Debe cambiar el valor y luego probar su escenario para observar los resultados. Nosotros esperamos tener más orientación oficial en esto en el futuro.

vez que haya una DataCacheFactory, que no necesita llamar GetCache() varias veces para obtener múltiples DataCache objetos. Cada llamada a GetCache() para el mismo caché en la misma fábrica devuelve el mismo objeto DataCache . Además, una vez que tiene el objeto DataCache, no necesita para continuar llamando al DataCacheFactory . Simplemente almacene el objeto DataCache y continúe usándolo. Sin embargo, no permita que se elimine el objeto DataCacheFactory. La vida del objeto DataCache es vinculada al objeto DataCacheFactory.

Nunca debe preocuparse por la contención con Obtener solicitudes. Sin embargo, con solicitudes Put/Add, puede haber una contención de si los clientes de caché de datos múltiples están actualizando la misma clave al al mismo tiempo. En este caso, obtendrá una excepción con con un código de error ERRCA0017, RetryLater y un subestado de ES0005, KeyLatched. Sin embargo, usted puede agregar fácilmente el manejo de excepciones y la lógica de reintento para intentar la actualización nuevamente cuando ocurran errores como estos. Esto se puede hacer para los códigos RetryLater con varios valores de subestado. Para más información, vea http://msdn.microsoft.com/en-us/library/ff637738.aspx. También puede usar el bloqueo pesimista utilizando las API GetAndLock() y PutAndUnlock(). Si utiliza este método , es su responsabilidad al asegurarse de que todos los clientes de la memoria caché utilicen el bloqueo pesimista . Una llamada Put() hará que borre un objeto que anteriormente estaba bloqueado por GetAndLock().

Espero que esto ayude. Como dije, nosotros esperamos obtener este tipo de orientación en pronto en algún contenido formal. Pero es mejor compartirlo aquí en el foro hasta entonces. ¡Gracias!

Jason Roth

+2

MaxConnectionsToServer es una configuración de configuración potente. Proporciona paralelismo sin codificación explícita de la misma. Asegúrese de implementar lógica para atrapar DataCacheExceptions y busque ErrorCode of RetryLater o Timeout para reintentos, porque los conflictos pueden ocurrir con mucha más frecuencia. – andrewbadera

4

hacer yo llamo GetCache ("cacheName") para cada solicitud objeto DataCache, o hacer presento una estática en el time DataCache factory se inicializa y lo usa para todas las llamadas?

Supongo que realmente la respuesta debería ser; pruébelo de ambas formas y vea si hay alguna diferencia, pero una DataCache estática tiene más sentido que una llamada correspondiente al GetCache para cada llamada a Get.

Ese artículo "Pushing Client Performance" sugiere que hay un punto positivo en el que la cantidad de instancias de DataCacheFactory le permite obtener un rendimiento máximo más allá del cual la memoria comienza a trabajar en su contra - es una pena que no hayan dado ninguna guía (o incluso una regla general) sobre dónde podría estar este lugar.

No he encontrado ninguna documentación sobre cómo maximizar el rendimiento. Creo que AppFabric todavía es demasiado nuevo para que estas directrices se hayan agotado todavía. Eché un vistazo a los Contenidos para el Pro AppFabric book, pero parece mucho más preocupado en general con el lado del flujo de trabajo (Dublín) de AppFabric que con el elemento de caché (Velocity).

Una cosa que diría sin embargo: ¿hay alguna posibilidad de que guarde en caché los objetos 'más gruesos' para que pueda hacer menos llamadas al Get? ¿Podría almacenar en caché colecciones en lugar de objetos individuales y luego descomprimir las colecciones en el cliente? 700 caché se obtiene por carga de página me parece ser un gran número!

+0

Sí, es un número enorme, pero estoy agregando un proveedor de almacenamiento en caché para un sistema desagradable y realmente no puedo cambiar sus requisitos básicos de almacenamiento en caché. Gracias por sus comentarios, aún resalta el hecho de que no hay mucha información buena para mi problema específico. – CRice

+2

Con respecto a extraer grandes cantidades de elementos de la caché, ¿ya echó un vistazo al etiquetado y la funcionalidad de la región? Si no tiene una lectura a través de esta publicación en el blog sobre el tema: http: //blogs.msdn.com/b/skaufman/archive/2010/04/22/tagging-objects-in-the-appfabric-cache.aspx – Rohland

+1

@Rohland Las etiquetas y regiones pueden ser una forma de simplificar parte del código al reducir el número de llamadas a cache.Get, pero no estoy seguro de que ofrezcan un beneficio de rendimiento significativo, ya que creo que el código aún sacará la misma cantidad de elementos del caché por página, es decir, creo que todavía estarás llegando a los mismos cuellos de botella. – PhilPursglove

Cuestiones relacionadas