将缓存与 SQL/NoSQL 数据库同步

NCache 通过自动将分布式缓存与 SQL Server、Oracle 和 NoSQL 数据库同步,提供实时数据一致性。这确保您的应用程序始终以亚毫秒级的性能提供最新数据,并通过事件驱动的通知和轮询消除过时数据。

NCache 是一个极快且线性可扩展的分布式缓存,它允许您缓存应用程序数据,从而提升应用程序的性能。缓存应用程序数据时,您会在缓存中创建一份数据副本,该副本也存在于数据库中。如果数据库中的数据发生变化,您需要确保缓存也进行更新,以始终与数据库保持一致。

为了处理这种情况, NCache 它提供强大的数据库同步功能,当关系型数据库或 NoSQL 数据库中的数据发生更改时,缓存会自动同步。这里的同步指的是从缓存中移除相应的缓存项(或重新加载它)。 通读). NCache 为数据库同步提供以下内容:

  1. SQL依赖
  2. Oracle依赖
  3. 与 MongoDB 同步缓存
  4. OleDB 依赖
  5. CLR 程序
  6. 带通读的自动重新加载

下图显示了如何实现的基本架构 NCache 支持数据库同步:

NCache 数据库同步架构:分布式缓存(Windows/Linux)通过实时事件通知与 SQL Server、Oracle、Cosmos DB 和 MongoDB 同步。
NCache 面向关系型数据库管理系统和 NoSQL 的实时数据库同步架构。

SQL 依赖

SQL依赖关系 由...使用 NCache 如果您的数据库是 SQL Server。 在缓存中添加或更新缓存项时,可以为任何缓存项指定 SqlDependency。 SQL Server 监视数据集的任何添加、更新或删除并通知 NCache 数据库更新后几乎立即通过 SQL 通知。这些数据库通知会转换为 .NET 事件。

SqlDependency 可以是以下任意一种:

  • 内联查询
  • 存储程序

您可以在 与 SQL Server 同步缓存 文档。

SQL依赖关系的工作原理

  • 触发: SQL Server 检测到数据更改(插入、更新或删除)。
  • 通知: SQL Server 向 .NET 发送事件通知 NCache.
  • 行动: NCache 自动使项目失效或重新加载以保持其完整性。

使用内联查询

下面展示了如何使用动态构造的 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);
}

与 MongoDB 同步缓存

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 依赖

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 程序

当缓存中有非常多的项目并且所有项目都需要与数据库同步时,最好写一个 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();
    }

使用 Read-Through 处理程序自动重新加载

数据库同步的默认行为是,当数据库中的相应数据发生更改时,从数据库中删除缓存项。但是,在某些情况下,您只是想使用最新版本的数据进行更新。

为了应对这种需求, NCache 允许您将数据库同步与 通读 的缓存功能 NCache. 有了这个, NCache 只需调用 Read-through 处理程序来重新加载缓存项的最新副本,然后用它更新缓存。 此功能提供了同步的灵活性 NCache 适用于任何已配置的关系型或 NoSQL 数据库,包括以下数据库(及更多):

  1. SQL服务器
  2. 神谕
  3. MongoDB的

以下代码片段展示了如何将数据批量自动重新加载到 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);

支持的同步环境

  • 关系: SQL Server、Oracle、PostgreSQL、MySQL(通过 OLEDB/CLR)。
  • NoSQL: MongoDB、Azure Cosmos DB。
  • 自定义: 通过自定义依赖项和读取处理程序获取任何数据源。

选择合适的同步机制

EventXtra XNUMX大解决方案 推荐机制 NCache 使用的功能
标准 SQL/Oracle 更新 数据库通知 SQL依赖关系 / Oracle依赖
大规模/批量更新 CLR 程序 CLR 存储过程(异步)
通用/传统数据库 轮询 数据库依赖关系 (通过 OLEDB)
NoSQL架构 变革流 通过自定义依赖项同步 MongoDB

接下来做什么?

常见问题

NCache 采用“基于通知”的同步模型。通过利用诸如以下功能: SQL依赖关系Oracle依赖当记录被更新或删除时,数据库会立即向缓存发送实时信号。这使得 NCache 立即使过期项目失效或重新加载。

是的。对于没有原生通知支持的数据库, NCache 提供基于轮询的依赖关系(DbDependency)。 NCache 定期检查数据库中的同步表是否有更改,使其与任何符合 OLEDB 标准的源兼容。

对于更新量巨大的环境,建议使用 CLR 存储过程。这些过程直接在 SQL Server 上执行,并进行异步调用。 NCache避免了数千个单独的 .NET 事件通知带来的开销。

当然。 NCache 它使用变更流与 MongoDB 同步,以实时检测集合更新。对于其他 NoSQL 数据源,您可以利用 NCache的读取提供程序会在数据过期或失效时自动重新加载数据。

NCache 旨在实现高可用性。如果与数据库的连接中断, NCache 可以配置为重试同步,或者依赖 TTL(生存时间)设置作为后备方案,以确保过时的数据不会无限期地保留下来。

联系我们

联系电话

+1 214-619-2601 (美国)

+44 20 7993 8327 (英国)

©版权所有 Alachisoft 2002 - 版权所有。 NCache 是 Diyatech Corp. 的注册商标。