NCache, un caché distribuida en memoria, mantiene sus datos intactos en un almacenamiento temporal para una experiencia más rápida de operaciones de lectura y escritura. Hemos visto NCache hacer maravillas con la velocidad cuando se trata de realizar operaciones en el almacén de caché. Sin embargo, manteniendo NCache sincronizado con la fuente de datos principal es un gran desafío cuando se trata de la consistencia de los datos. La fuente de datos puede ser cualquier base de datos; sin embargo, este blog trata sobre cómo mantener su caché sincronizada con PostgreSQL.
Dos copias de datos separadas: un desafío
La pila de su aplicación funciona con NCache como el caché reside como una capa de almacenamiento en caché entre la base de datos y la aplicación. Su aplicación está conectada directamente al caché, por lo que envía todas las llamadas de operación directamente al caché, como lectura o escritura. Supongamos que otro usuario cambia algo en la base de datos sin avisar al caché. Ahora los datos en la base de datos son diferentes de los datos que residen en el caché. Las dos copias separadas de los datos dan como resultado una inconsistencia en los datos, lo cual es un gran desafío.
NCache Detalles NCache Docs Sincronizar caché con PostgreSQL
NCache Mantener los datos sincronizados
Dado el desafío de la inconsistencia de los datos, NCache se precipita con una solución para eso, como todo lo demás. Lo que debe hacer es sincronizar su caché con la base de datos usando NCache sincronización de base de datos tecnicas La base de datos discutida en este blog, como se mencionó anteriormente, es PostgreSQL, una base de datos relacional de objetos de código abierto con un conjunto de funciones bien desarrollado y alto rendimiento y confiabilidad. Tenemos una solución hecha y cargada en GitHub en Sincronizando el caché con PostgreSQL que muestra cómo su caché puede mejorar la escalabilidad y la coherencia de los datos.
El siguiente diagrama muestra cómo funciona NCache ayudarlo a mantener los datos sincronizados con su base de datos PostgreSQL.
Sincronizando NCache con base de datos PostgreSQL
NCache le permite mantener sus datos sincronizados con PostgreSQL usando NotifyExtensibleDependencyNotifyExtensibleDependency, que es una técnica de sincronización proporcionada por NCache para mantener la caché y la base de datos sincronizadas. NotifyExtensibleDependency se utiliza para implementar la técnica de invalidación de datos utilizando el sistema de notificación de dependencia de PostgreSQL. La dependencia de PostgreSQL se basa en el mecanismo LISTEN/NOTIFY que es similar al Modelo de publicación/suscripción.
Junto con la dependencia de la base de datos, Proveedor de lectura a través se utiliza para comunicarse directamente con la fuente de datos. NCache llama al proveedor para cargar datos desde la fuente de datos directamente usando su lógica personalizada. Esto mantiene los datos sincronizados y actualizados para evitar problemas como datos obsoletos, además de proporcionar una escalabilidad mejorada y operaciones de lectura más rápidas.
Entonces, los componentes básicos involucrados son:
-
- NotificarExtensibleDependency: NCache se registra con un canal específico llamando a LISTEN dentro de NotifyExtensibleDependency
Initialize
método. En la base de datos, se invoca una función TRIGGER que envía un Payload al canal y al escuchar, en caso de inconsistencia de datos, los datos se eliminan del caché. - ReadThruProvider: este proveedor obtiene los datos actualizados automáticamente, directamente desde la base de datos tras la modificación de datos en la base de datos.
- NotificarExtensibleDependency: NCache se registra con un canal específico llamando a LISTEN dentro de NotifyExtensibleDependency
NCache Detalles Leer de parte a parte Dependencia basada en notificaciones
Sincronizar caché usando NotifyExtensibleDependency
NotifyExtensibleDependencyNotifyExtensibleDependency se utiliza para invalidar los datos utilizando el mecanismo de dependencia de PostgreSQL, que funciona en el modelo de Mensajes de publicación/suscripción y el modelo se llama Listen/Notify. De acuerdo con este mecanismo, cualquier actualización en la base de datos se pasa al cliente que escucha en un canal específico a través de un comando NOTIFY con una carga útil adicional que contiene la información. El cliente en nuestro caso concreto es NCache y al ser notificado sobre cualquier cambio en la base de datos, el elemento correspondiente se elimina del caché.
Veamos el código a continuación para ver cómo se agrega un elemento con la dependencia de PostgreSQL:
1 2 3 4 5 6 7 8 9 10 11 |
const string connectionString = "your-connection-string"; var customer = new Customer(); var cacheItem = new CacheItem(customer) { Dependency = new PostGreSQLDependency(connectionString, customer.customerid, "public", "customers", "customer_channel") }; var key = customer.customerid; var cache = CacheManager.GetCache("democache"); cache.Insert(key, cacheItem); |
Sin embargo, es necesario comprender la implementación de PostgreSQLDependency
y el siguiente código ayudará. Él Initialize
El método contiene una cadena de conexión para conectarse a la base de datos y se registra para recibir notificaciones sobre cualquier modificación de datos en los datos específicos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public PostGreSQLDependency(string connectionString, string dependencyKey, string schema, string table, string channel) { _connectionString = connectionString.Trim(); _dependencyKey = dependencyKey.Trim(); _schema = schema.Trim(); _table = table.Trim(); _channel = channel.Trim(); } public override bool Initialize() { connection = new NpgsqlConnection(_connectionString); connection.Open(); ((NpgsqlConnection)connection).Notification += (o, e) => { var entity = JsonConvert.DeserializeObject(e.AdditionalInformation); if (entity.DependencyKey == _dependencyKey && entity.Table == _table && entity.Schema == _schema) { done = true; } }; using (var cmd = new NpgsqlCommand($"LISTEN {_channel};", (NpgsqlConnection)connection)) { cmd.ExecuteNonQuery(); } task = Task.Run(() => { while (true) { ((NpgsqlConnection)connection).Wait(); if (done) { break; } } this.DependencyChanged.Invoke(this); }); return true; } |
NCache Detalles NCache Docs Sincronizar caché con PostgreSQL
Recarga automática de datos mediante lectura simultánea
Usando la dependencia, cada vez que se modifican los datos en la fuente de datos, se borran de la memoria caché. Sin embargo, todavía necesitamos recargar esos datos en el caché también y para eso NCache tiene una característica llamada Fuente de respaldo. Brindamos al proveedor de lectura directa la libertad de agregar su lógica personalizada en la implementación. En el caso especificado, el proveedor Read-Through carga datos de la base de datos PostgreSQL. Necesitas configurar el proveedor de lectura directa utilizando las herramientas de gestión antes.
El uso de opciones de resincronización en el proveedor de lectura directa mantiene los datos sincronizados con la base de datos. Sin embargo, dentro del ProviderCacheItem
, CacheItem tiene una dependencia agregada, lo que significa que el nuevo elemento agregado en el caché viene con una dependencia ya agregada. Le ahorra el esfuerzo de agregar dependencia una y otra vez. mira el LoadFromSource
dentro del proveedor Read-Through para ver la implementación:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public ProviderCacheItem LoadFromSource(string key) { var query = $"SELECT customerid, address, country, city FROM customers WHERE customerid = '{key}'"; // Define a query returning a single row result set NpgsqlCommand command = new NpgsqlCommand(query, _connection as NpgsqlConnection); var reader = command.ExecuteReader(); ProviderCacheItem providerCacheItem = null; while (reader.Read()) { if (providerCacheItem == null) { var customer = new Customer() { customerid = reader[0] as string, address = reader[1] as string, country = reader[2] as string, city = reader[3] as string, }; providerCacheItem = new ProviderCacheItem(customer) { Dependency = new PostGreSQLDependency(_connectionString, customer.customerid, "public", "customers", "customer_channel"), ResyncOptions = new ResyncOptions(true) }; } } } |
Al agregar el elemento con lectura directa ahora, simplemente carga los elementos modificados directamente en el caché usando dependencia de la base de datos. Por lo tanto, su caché permanece sincronizada con la base de datos PostgreSQL y todos sus problemas de datos obsoletos desaparecen.
Conclusión
Para poner todo en el blog en términos simples, su caché y base de datos deben permanecer sincronizados entre sí. Si el caché no está al tanto de las modificaciones realizadas en la base de datos, su aplicación puede seguir funcionando y trabajando con datos de caché obsoletos. Este problema se resuelve muy eficientemente con NCache Función de dependencia de PostgreSQL. Hay toneladas de otras características geniales que puedes ver simplemente yendo a NCache página web del NDN Collective .
NCache Detalles Comparación de ediciones NCache Descargar