NCache 通过自动将分布式缓存与 SQL Server、Oracle 和 NoSQL 数据库同步,提供实时数据一致性。这确保您的应用程序始终以亚毫秒级的性能提供最新数据,并通过事件驱动的通知和轮询消除过时数据。
NCache 是一个极快且线性可扩展的分布式缓存,它允许您缓存应用程序数据,从而提升应用程序的性能。缓存应用程序数据时,您会在缓存中创建一份数据副本,该副本也存在于数据库中。如果数据库中的数据发生变化,您需要确保缓存也进行更新,以始终与数据库保持一致。
为了处理这种情况, NCache 它提供强大的数据库同步功能,当关系型数据库或 NoSQL 数据库中的数据发生更改时,缓存会自动同步。这里的同步指的是从缓存中移除相应的缓存项(或重新加载它)。 通读). NCache 为数据库同步提供以下内容:
下图显示了如何实现的基本架构 NCache 支持数据库同步:
SQL依赖关系 由...使用 NCache 如果您的数据库是 SQL Server。 在缓存中添加或更新缓存项时,可以为任何缓存项指定 SqlDependency。 SQL Server 监视数据集的任何添加、更新或删除并通知 NCache 数据库更新后几乎立即通过 SQL 通知。这些数据库通知会转换为 .NET 事件。
SqlDependency 可以是以下任意一种:
您可以在 与 SQL Server 同步缓存 文档。
下面展示了如何使用动态构造的 SQL 查询创建 SQL 依赖项:
// Precondition: Cache is already connected
// Creating a connection string to get connected with the database
string connectionString = "your_connection_string_here";
// Getting products from the database
List<Product> products = FetchProductFromDB();
foreach (Product product in products)
{
string productKey = $"Product: {product.ProductID}";
// Creating an SQL dependency on the UnitPrice of product. Whenever the UnitPrice changes, the product is removed from the cache
string query = $"SELECT UnitPrice FROM dbo.Products WHERE ProductID = {product.ProductID}";
// Creating dependency
SqlCacheDependency dependency = new SqlCacheDependency(connectionString, query);
CacheItem productItem = new CacheItem(product);
// Adding Dependency to product item
productItem.Dependency = dependency;
// Adding CacheItem in cache
_cache.Add(productKey, productItem);
}
以下是如何在 .NET 代码中使用带有存储过程的 SQL 依赖项:
// Precondition: Cache is already connected
// Creating connection string to get connected with the database
string connectionString = "your_connection_string_here";
string spGetUnitPriceByProductID = "sp_GetUnitPriceByProductID";
// Getting products from the database
List<Product> products = FetchProductFromDB();
// Creating dictionary of CacheItems
Dictionary<string, CacheItem> cacheItems = new Dictionary<string, CacheItem>();
foreach (Product product in products)
{
string productKey = $"Product: {product.ProductID}";
// Creating Param to be passed in stored procedure dictionary
SqlCmdParams paramProductID = new SqlCmdParams
{
Type = CmdParamsType.Int,
Value = product.ProductID
};
// Creating stored procedure params
Dictionary<string, SqlCmdParams> parameters = new Dictionary<string, SqlCmdParams>();
parameters.Add("@ProductID", paramProductID);
CacheItem productItem = new CacheItem(product);
// Creating an SQL dependency on the UnitPrice of the product. Whenever the UnitPrice changes, the product is removed from the cache
SqlCacheDependency dependency = new SqlCacheDependency(connectionString, spGetUnitPriceByProductID, SqlCommandType.StoredProcedure, parameters);
// Adding Dependency to product item
productItem.Dependency = dependency;
cacheItems.Add(productKey, productItem);
}
// Adding CacheItems in cache
_cache.AddBulk(cacheItems);
NCache 利用 Oracle 的持续查询通知 (CQN) 来监控数据库变更。与传统的轮询方式不同,这种基于推送的机制确保 Oracle 服务器仅与需要变更的数据库进行通信。 NCache 当 SQL 查询定义的特定数据集发生更改时,此操作会显著降低网络开销并确保实时缓存同步。
Oracle依赖 由...使用 NCache 如果您的数据库是 Oracle 10g 或更高版本并在 Windows 或 Unix 上运行。 就像 SqlDependency 一样,您可以在缓存中添加或更新缓存项时为任何缓存项指定 OracleDependency。
OracleDependency 可以是以下任意一种:
然后,Oracle 服务器会监视该数据集是否有任何添加、更新或删除,当发生这种情况时,它会通知 NCache 数据库更新后几乎立即通过 Oracle 通知。
下面介绍了如何使用内联查询在 .NET 代码中使用 Oracle 依赖项:
// Precondition: Cache is already connected
// Creating a connection string to get connected with the database
string connectionString = "your_connection_string_here";
// Getting products from the database
List<Product> products = FetchProductFromDB();
foreach (Product product in products)
{
string productKey = $"Product: {product.ProductID}";
// Creating an Oracle dependency on the UnitPrice of the product. Whenever the UnitPrice changes, the product is removed from the cache
string query = $"SELECT ROWID, UnitPrice FROM Products WHERE ProductID = {product.ProductID}";
OracleCacheDependency dependency = new OracleCacheDependency(connectionString, query);
CacheItem productItem = new CacheItem(product);
// Adding Dependency to product item
productItem.Dependency = dependency;
// Adding CacheItem in cache
cache.Add(productKey, productItem);
}
您可以在 Oracle 依赖项中使用参数化存储过程调用,如下所示:
// Precondition: Cache is already connected
// Creating a connection string to get connected with the database
string connectionString = "your_connection_string_here";
string spGetUnitPriceByProductID = "sp_GetUnitPriceByProductID";
// Getting products from the database
List<Product> products = FetchProductFromDB();
foreach (Product product in products)
{
string productKey = $"Product: {product.ProductID}";
// Creating Param to be passed in stored procedure dictionary
OracleCmdParams paramProductID = new OracleCmdParams
{
Type = OracleCmdParamsType.Int32,
Value = product.ProductID
};
// Creating stored procedure params
Dictionary<string, OracleCmdParams> parameters = new Dictionary<string, OracleCmdParams>();
parameters.Add("@ProductID", paramProductID);
CacheItem productItem = new CacheItem(product);
// Creating an Oracle dependency on the UnitPrice of the product. Whenever the UnitPrice changes, the product is removed from the cache
OracleCacheDependency dependency = new OracleCacheDependency(connectionString, spGetUnitPriceByProductID, OracleCommandType.StoredProcedure, parameters);
// Adding Dependency to product item
productItem.Dependency = dependency;
// Adding CacheItem in cache
cache.Add(productKey, productItem);
}
NCache 通过自定义通知依赖项,提供对缓存失效的灵活性和控制。对于 MongoDB,您可以使用变更流实时同步缓存和 MongoDB 数据库。
这可以检测 MongoDB 集合上的插入、更新、删除和替换。 NCache 当发生更改时可以立即删除或更新相应的缓存条目,确保您的缓存保持最新并与数据库保持一致。
以下是如何在 .NET 应用程序中使用 MongoDB 的变更流实现此同步的示例:
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<Customer>>()
.Match("{ operationType: { $in: ['insert', 'update', 'replace', 'delete'] } }");
var cursor = collection.Watch(pipeline);
await cursor.ForEachAsync(change =>
{
string cacheKey = $"Customer:CustomerID:{change.FullDocument.Id}";
cache.Remove(cacheKey);
});
OleDB 依赖 由...使用 NCache 如果您的数据库既不是 SQL Server 也不是 Oracle,而是兼容 OLEDB 的数据库。如果您不想接收 SQL Server 和 Oracle 的事件通知,也可以将 DbDependency 与 SQL Server 和 Oracle 一起使用,因为如果数据变化非常快,事件通知可能会变得非常繁琐。
在 DbDependency 中,您需要在数据库中创建一个名为 ncache_db_sync 的表,该表为每个具有 DbDependency 的缓存项包含一行。您可以修改数据库触发器,以便在数据库中的相应数据发生变化时更新此表中的行。 NCache 轮询此表以获取更新的行,因此在一次轮询中, NCache 获取数千行并将它们与数据库同步。
以下是在 .NET 代码中使用 DbDependency 的方法。
DBCacheDependency oledbDependency = DBDependencyFactory.CreateOleDbCacheDependency(connectionString, "PrimaryKey:dbo.Products");
var cacheItem = new CacheItem(product);
cacheItem.Dependency = oledbDependency;
cache.Insert(key, cacheItem);
当缓存中有非常多的项目并且所有项目都需要与数据库同步时,最好写一个 CLR 程序 在 Windows 上的 SQL Server 中。 当相关数据发生变化时,从您的数据库触发器中调用此 CLR 过程。 然后,此 CLR 过程使异步 NCache 用于从缓存中添加、更新或删除相应缓存项的 API 调用。
下面是一个 CLR 过程的示例,该过程在对象被更新时将其删除。
[Microsoft.SqlServer.Server.SqlProcedure]
public static void RemoveOnUpdate(string cacheName, string key)
{
// Connect to the cache
ICache cache = CacheManager.GetCache(cacheName);
// Remove specified item
cache.Remove(key);
// Dispose the cache
cache.Dispose();
}
数据库同步的默认行为是,当数据库中的相应数据发生更改时,从数据库中删除缓存项。但是,在某些情况下,您只是想使用最新版本的数据进行更新。
为了应对这种需求, NCache 允许您将数据库同步与 通读 的缓存功能 NCache. 有了这个, NCache 只需调用 Read-through 处理程序来重新加载缓存项的最新副本,然后用它更新缓存。 此功能提供了同步的灵活性 NCache 适用于任何已配置的关系型或 NoSQL 数据库,包括以下数据库(及更多):
以下代码片段展示了如何将数据批量自动重新加载到 NCache 使用 Read-through 从数据库中读取。您还可以找到更多详细信息 开始.
String[] keys = { "Product:1001", "Product:1002",
"Product:1003","Product:1004"};
// Specify the readThruOptions for Read-through operations
var readThruOptions = new ReadThruOptions();
readThruOptions.Mode = ReadMode.ReadThru;
// Retrieve the dictionary of Products with corresponding products
IDictionary<string, Product> retrievedItems = cache.GetBulk<Product>(keys, readThruOptions);
| EventXtra XNUMX大解决方案 | 推荐机制 | NCache 使用的功能 |
|---|---|---|
| 标准 SQL/Oracle 更新 | 数据库通知 | SQL依赖关系 / Oracle依赖 |
| 大规模/批量更新 | CLR 程序 | CLR 存储过程(异步) |
| 通用/传统数据库 | 轮询 | 数据库依赖关系 (通过 OLEDB) |
| NoSQL架构 | 变革流 | 通过自定义依赖项同步 MongoDB |