Podemos poner un servidor de caché entre nuestra aplicación y la base de datos para que nuestras aplicaciones sean más rápidas. Pero eso no es suficiente cuando necesitamos escalar nuestras aplicaciones. Veamos dos patrones de almacenamiento en caché para un mejor rendimiento y cómo NCache las implementa.
Escalabilidad a través del particionamiento de datos
Con la partición de datos, dividimos grandes conjuntos de datos en otros más pequeños y los distribuimos entre los nodos. De esta forma, dividimos las lecturas y escrituras entre nodos, mejorando el rendimiento general de nuestras aplicaciones. NCache admite diferentes topologías de almacenamiento en caché. En este contexto, una topología es una estrategia de conectividad de cliente, replicación y almacenamiento de datos. Hay dos topologías que implementan la partición de datos: la Topologías con particiones y réplicas de particiones. En estas dos topologías, NCache divide los datos en cubos y coloca esos cubos en los nodos de nuestro clúster.
NCache utiliza 1000 cubos y los divide equitativamente entre los nodos de un clúster. Por ejemplo, si iniciamos un clúster de caché con un solo nodo, NCache asigna todos los cubos a nuestro único nodo. Si añadimos otro nodo, NCache divide esos 1000 cubos en dos nodos de 500 cubos. Además, si eliminamos un nodo, NCache distribuye sus cubos en los nodos restantes.
Como NCache divide nuestros datos en depósitos y nodos, un cliente de caché se conecta a todos los nodos pero realiza operaciones de lectura y escritura directamente en el nodo que contiene un elemento. Incluso si un nodo no está disponible, un cliente de caché redirige nuestras solicitudes utilizando los nodos activos para finalizar nuestras operaciones. NCache distribuye cubos entre los nodos manteniendo el tamaño de los datos en cada nodo casi igual. De esta forma, no solo dividimos las lecturas y escrituras entre nodos, sino que también aumentamos la capacidad de almacenamiento de nuestro clúster con cada nodo que agregamos.
Gracias a la partición de datos, las topologías Partition y Partition-Replica escalan la carga de transacciones y la capacidad de almacenamiento. Por supuesto, Partition y Partition-Replica son solo dos de las topologías admitidas. NCache tiene mas topologías con diferentes estrategias de almacenamiento y replicación de datos. Por ejemplo, algunos de ellos son adecuados para aplicaciones con más lecturas o escrituras.
Estrategias de almacenamiento en caché
Con el particionamiento de datos, mejoramos la disponibilidad y el rendimiento de nuestras aplicaciones, ya que podemos almacenar en caché más elementos en nuestro clúster que en un solo servidor. Además, podemos mejorar el rendimiento de nuestra aplicación eligiendo cómo llenamos nuestra memoria caché. Hay dos estrategias para llenar nuestra memoria caché: memoria caché aparte y lectura simultánea/escritura simultánea.
Con la estrategia de caché aparte, nuestro servidor de caché se encuentra junto a nuestra base de datos. Si nuestro caché no contiene un elemento, nuestra aplicación lo lee de nuestra base de datos y lo almacena en el caché. Con esta estrategia, el servidor de caché no interactúa directamente con nuestra base de datos. Probablemente, la estrategia de reserva de caché es lo primero que nos viene a la mente cuando pensamos en el almacenamiento en caché.
A diferencia de la estrategia de caché aparte, con las estrategias Read-Through/Write-Through, nuestra caché funciona como la principal fuente de datos. Aquí, nuestro caché lee y escribe datos en la base de datos. Por lo tanto, estas estrategias funcionan mejor con datos de referencia que leemos con frecuencia y cambiamos periódicamente, y con las filas de la base de datos podemos mapear fácilmente a elementos de caché.
Con Read-Through/Write-Through, movemos parte del código de acceso a datos de nuestra aplicación al caché, lo que hace que el código de nuestra aplicación sea más simple y más pequeño. NCache admite las estrategias de almacenamiento en caché Read-Through y Write-Through.
Almacenamiento en caché de lectura
NCache utiliza un proveedor de lectura directa personalizado para llamar a la base de datos subyacente si hay una falta de memoria caché. Además, podemos forzar NCache para leer siempre la base de datos, incluso si no tenemos una pérdida de caché. Nuestro proveedor Read-Through debe implementar el Interfaz IReadThruProvider. Contiene métodos como CargarDesdeFuente y Cargar tipo de datos desde fuente.
Una vez que tenemos un Proveedor de lectura implementado en nuestro servidor de caché, ya sea a través de la NCache Manager o scripts de PowerShell, podemos usarlo desde nuestras aplicaciones cliente pasando el objeto ReadThruOptions como parámetro al método Get, así,
1 2 3 4 5 6 7 8 9 10 11 |
// After having NCache up and running... var key = $"Product:123456"; var readThruOptions = new ReadThruOptions { Mode = ReadMode.ReadThru }; // Retrieve a cached item with Read-Thru enabled var data = cache.Get<Product>(key, readThruOptions); // Do something with the cached product here... |
Almacenamiento en caché de escritura simultánea
Por otro lado, con la estrategia Write-Through, NCache actualiza primero nuestra caché y, solo después, nuestra base de datos. NCache puede actualizar nuestra base de datos ya sea de forma síncrona o asíncrona. NCache llama a las actualizaciones asincrónicas de escritura directa: Escritura posterior.
Nuestro proveedor de Write-Through debe implementar el Interfaz IWriteThruProvider. Contiene el método WriteToDataSource con sobrecargas para elementos únicos y múltiples, y estructuras de datos. Nuestro proveedor de escritura simultánea debe admitir operaciones de escritura para agregar, eliminar y actualizar elementos.
De manera similar a la implementación de un proveedor Read-Through, necesitamos implementar nuestro Proveedor de escritura simultánea a nuestro caché. Una vez que implementemos nuestro proveedor, en nuestras aplicaciones cliente, debemos pasar el Opciones de escritura a través objeto al insertar elementos en el caché, como este,
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// After having NCache up and running... var product = BuildProduct(); var key = $"Product:{product.ProductId}"; var cacheItem = new CacheItem(product); var writeThruOptions = new WriteThruOptions { Mode = WriteMode.WriteThru; } // Add an item with Write-Thru enabled cache.Insert(key, cacheItem, writeThruOptions); |
Read-Through y Write-Through nos ayudan a mejorar la escalabilidad y el rendimiento de nuestras aplicaciones. Con Read-Through, nuestros elementos almacenados en caché están siempre disponibles desde NCache puede leer artículos vencidos automáticamente. Y, con Write-through, nuestra aplicación no tiene que esperar escrituras en la base de datos ya que NCache puede actualizar nuestra base de datos de forma asíncrona e, incluso con un mecanismo de aceleración, reduciendo la presión sobre nuestra base de datos.
Conclusión
Esos son dos patrones de almacenamiento en caché para un mejor rendimiento y escalabilidad: partición de datos y estrategias de almacenamiento en caché. Nosotros podemos usar NCache implementarlos en nuestras aplicaciones. Con el particionamiento de datos, dividimos las lecturas y escrituras entre nodos y aumentamos la capacidad de almacenamiento de nuestra memoria caché. Tenemos NCache Topologías de partición y réplica de partición para eso. Y con Read-Through/Write-Through, hacemos que nuestro servidor de caché sea la fuente de datos, eliminando algo de presión de nuestra base de datos.
Para conocer más detalles sobre el particionamiento de datos y la lectura/escritura simultánea, consulte estas dos guías: Topologías con particiones y réplicas de particiones y Proveedores de fuentes de datos para caché. Si desea beneficiarse de estos dos patrones de almacenamiento en caché para escalar sus aplicaciones, proporcione NCache un intento.