如果您的应用程序严重依赖数据库,缓存对于克服与数据库相关的问题至关重要,尤其是在高流量情况下。对于使用缓存来加速数据检索的在线应用程序,实现强大的数据复制是保持一致性和可用性的关键。
数据复制对于在多个服务器上创建重要缓存数据的备份、保持数据完整性和保证高可用性至关重要。同样,这种同步机制对于防止任何应用程序流程差异至关重要。因此,您必须尽最大努力创建全面的数据复制策略。幸运的是, NCache 意识到这种复制和同步机制的重要性,并为用户提供了多种选择,如下面的博客中所述。
关键要点:
数据复制: NCache 提供同步和异步复制,以确保跨多个服务器节点的数据可用性和容错能力。
拓扑多样性: 用户可以选择镜像(主备模式)、复制(所有节点上的完整副本)或分区副本(带备份的可扩展分区)来平衡性能和冗余。
一致性控制: 通过分布式锁定来维护强大的数据完整性,通过项目版本控制提供乐观锁定,并通过对项目进行独占访问提供悲观锁定。
无效化策略: 通过基于时间的过期时间和数据库依赖关系来进一步加强一致性,以消除过时的数据并确保缓存与主数据源匹配。
NCache 拓扑结构
支持的几种缓存拓扑 NCache ( 镜像, 已复制和 分区副本拓扑(如下所述)强调了这种能力。
| 拓扑 | 复制 | 主要好处 | 容错 |
|---|---|---|---|
| 镜子 | Synchronous | 高可用性(主动-被动) | 1. 节点故障(自动故障转移) |
| 已复制 | 异步 | 最大读取可扩展性 | 多节点(完全数据冗余) |
| 分区副本 | 同步/异步 | 具有冗余性的可扩展性 | 可配置(基于副本数) |
- 镜像拓扑: 在镜像拓扑中,缓存集群包含两个节点,每次只有一个节点处于活动状态,另一个节点则作为被动节点。本质上,在镜像缓存拓扑中,所有读写操作都仅连接到集群的活动服务器节点。如果活动节点发生故障,被动节点会自动接管,从而确保高可用性,且不会出现任何问题。
- 复制拓扑: 此拓扑结构在集群中的所有服务器节点上复制缓存数据。每个节点都包含缓存的完整副本,因此即使多个节点发生故障,也不会丢失数据。
- 分区副本拓扑: 分区-副本拓扑不仅创建了分区拓扑中可用的动态分区以实现可扩展性,还创建了这些分区在其他服务器节点上的动态副本,在发生连接故障或节点故障时充当备份。在这些情况下, NCache 从副本节点获取缓存数据,并按要求进行分发。
在博客中了解有关拓扑的更多信息: 横向扩展和保持向上:探索拓扑 NCache.
数据复制在 NCache
数据复制的主要目标是确保数据可用性、一致性和容错性。通过在不同位置维护相同的数据副本,系统可以提高性能并减少延迟,同时防止潜在的数据丢失或服务器故障。数据复制是同步的或异步的,具体取决于所使用的拓扑,如下所述。
- 同步复制: 通过同步复制, NCache 确保数据同时写入主缓存服务器及其副本。然而,虽然这种方法推荐用于需要高可用性的场景,但由于任何缓存写入操作都必须等待所有副本的确认,因此应用程序性能可能会受到影响。
- 异步复制: 或者,异步复制在将数据写入主缓存服务器后更新副本。此方法允许在不等待副本确认的情况下完成写入操作,从而提高了性能。但是,此策略可能会导致副本和主缓存服务器之间出现暂时的数据不一致。
同步和异步数据复制的拓扑
讨论的每种拓扑都提供了自己的一组特性,但并非所有拓扑都适用于数据复制。例如,在 镜像缓存拓扑,通过同时写入主节点和副本节点来保证数据一致性。 另一方面,通过先写入主节点,然后更新副本,异步复制,用于 复制缓存拓扑,提高了效率,但有时也会导致错误。然而,复制也有其问题,例如,当数据量呈指数增长时,就需要对数据进行分区。
幸运的是 分区副本拓扑 通过结合分区和复制缓存拓扑的优点,在可用性、冗余和性能之间取得平衡。您可以根据自己的需求选择最适合自己的技术。
数据一致性机制
NCache 允许开发人员根据所选拓扑和复制模式,调整一致性和可用性之间的平衡,以符合 CAP 定理的不同要求。数据一致性是指无论用户操作如何,整个应用程序堆栈中信息的可靠性和准确性。为了确保数据一致性, NCache 提供了一个 分布式锁定 允许您在更新期间锁定特定缓存项的机制。因此,通过在组件级别应用锁定,多个用户可以同时处理各种缓存项,而不会损害其数据完整性。因此,缓存锁对于管理分布式环境中的共享资源非常有用。
NCache 为您提供两种类型的锁定: 乐观锁定(缓存项版本) 和 悲观锁定(排他锁定)乐观锁定使用缓存项版本控制。在这种类型的锁定中, 添加 方法在缓存中添加新项目并首次保存项目版本,而 插页 方法覆盖现有项目的值并更新其项目版本。
下面的示例创建一个 锁柄 然后使用密钥 Product:1001 和项目版本锁定一个项目。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// An item is added in the cache with itemVersion // Specify the key of the cacheItem string key = "Product:1001"; // Initialize the cacheItemVersion CacheItemVersion version = null; // Get the cacheItem previously added in the cache with the version CacheItem cacheItem = cache.GetCacheItem(key, ref version); // If result is not null and version is valid if (cacheItem != null && version != null) { // CacheItem is retrieved successfully with the version // If result is of type Product var prod = cacheItem.GetValue<Product>(); prod.UnitsInStock++; else { // Item could not be retrieved; it might not exist or the version is outdated Console.WriteLine("Cache item could not be retrieved or version is invalid."); } |
或者,悲观锁定使用 Lock Handle 锁定项目,阻止所有其他用户对该缓存项目执行任何写入操作。在获取项目时成功获取锁定后,应用程序现在可以安全地对该项目执行操作,因为知道在释放锁定之前没有其他应用程序可以访问或修改它。以下示例锁定缓存中的项目,然后使用 LockHandle 获取该项目。然后使用 Insert API 更新该项目并将其重新插入缓存中。
|
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 |
// Specify the key of the item string key = $"Product:1001"; // Set acquireLock flag as true bool acquireLock = true; // Specify time span of 10 seconds for which the item remains locked TimeSpan lockSpan = new TimeSpan(0, 0, 10); // Initialize the lockHandle LockHandle lockHandle = null; CacheItem item = cache.GetCacheItem(key, acquireLock, lockSpan, ref lockHandle); var product = new Product(); product = item.GetValue<Product>(); // Update the unitsinstock for the product product.UnitsInStock = 200; bool releaseLock = true; // Item is already locked with a LockHandle // Update the item and release the lock as well since releaseLock is set true // Make sure that the LockHandle matches with the already added LockHandle cache.Insert(key, item, null, lockHandle, releaseLock); |
数据复制和一致性的附加机制
现在我们已经了解了提供的数据复制和一致性机制 NCache,让我们探索可以采用的其他数据一致性和数据复制策略。例如, NCache 支持基于时间的数据失效策略,使缓存数据过期。通过 過期时间 意味着您可以设置数据在缓存中保留的特定时间,超过该时间数据将过期。这样,您的缓存将在下一个客户端请求时拥有新数据,从而消除陈旧数据并确保数据一致性。此外,通过 依赖 确保每当数据库发生更改时都会删除缓存数据。
结语
数据复制和一致性是可靠和高性能应用程序的支柱。 幸运的是,与 NCache,您可以使用强大的功能来创建高度可扩展、容错的应用程序,这些应用程序甚至可以处理最复杂的数据需求。 为什么要等待? 下载 NCache 今天就将您的应用程序性能提升到新的水平!
常见问题
问:镜像拓扑在节点故障期间如何处理客户端连接?
答:在镜像拓扑中,客户端仅连接到活动服务器节点进行读写操作。如果活动节点发生故障,被动节点会自动接管。 NCache 重定向客户端连接以确保持续可用性。
问:选择同步复制而不是异步复制时,性能方面有哪些权衡?
答:同步复制确保数据在确认写入之前同时写入所有副本,从而提供最高的数据一致性,但会增加延迟。异步复制允许写入操作在主节点更新后立即完成,从而提高性能,但代价是在后台更新期间可能出现暂时的数据不一致。
问:开发人员何时应该选择乐观锁(项目版本控制)而不是悲观锁?
答:乐观锁非常适合数据冲突较少的高并发环境,因为它允许用户在不阻塞其他用户的情况下修改数据项。它利用数据项版本控制来检测自上次获取数据项以来是否发生了更改。悲观锁更适合关键数据段,因为这类数据段需要绝对独占访问权限以防止任何并发修改。
问:缓存依赖关系如何促进数据一致性?
答:缓存依赖关系确保缓存与主数据源之间的同步。通过将缓存项链接到数据库, NCache 当检测到数据库中发生更改时,会自动使数据失效或删除,防止应用程序使用过时的信息。






