【问题标题】:Lock cache with Apache Ignite.NET thin client使用 Apache Ignite.NET 瘦客户端锁定缓存
【发布时间】:2020-10-20 21:28:42
【问题描述】:

目前我们使用 Apache Ignite.NET 瘦客户端来缓存不同的数据集。当数据请求到来时,我们检查数据是否已经存储在缓存中,如果没有,则从数据库中请求数据并将其放入缓存中。

如果同时出现两个数据请求,我想阻止多个数据库请求。 有没有办法在第一个数据库请求开始之前手动锁定缓存?因此第二个数据请求可以等到第一个请求完成。

我无法解决使用 .NET 并发原语的任务,因为缓存可以被多个客户端实例使用(负载平衡)。

我已经找到 ICache.Lock(TK key) 方法,但它似乎只锁定缓存中的指定行,并且仅在自托管模式下受支持,不适用于 Ignite.NET 这个客户端。

说明问题的一小段代码:

var key = "cache_key"; 

using (var ignite = Ignition.StartClient(new Core.Client.IgniteClientConfiguration { Host = "127.0.0.1" }))
{
    var cacheNames = ignite.GetCacheNames();
    if (cacheNames.Contains(key))
    {
        return ignite.GetCache<int, Employee>(key).AsCacheQueryable();
    }
    else
    {
        var data = RequestDataFromDatabase();

        var cache = ignite.CreateCache<int, Employee>(new CacheClientConfiguration(
            EmployeeCacheName, new QueryEntity(typeof(int), typeof(Employee))));

        cache.PutAll(data);

        return cache.AsCacheQueryable();
    }
}

【问题讨论】:

    标签: c# .net ignite


    【解决方案1】:

    瘦客户端没有所需的 API。

    如果您不需要检查单个记录,而只需要知道缓存是否可用,则可以多次调用 CreateCache。它应该抛出一个异常,说明具有特定名称的缓存已经启动以供进一步调用。

    try {
        var cache = ignite.CreateCache<int, Employee>(new CacheClientConfiguration(
                EmployeeCacheName, new QueryEntity(typeof(int), typeof(Employee))));
        // Cache created by this call => add data here
    } catch (IgniteClientException e)  when (e.Message.Contains("already started")) {
        // Return existing cache, don't add data
    }
    

    【讨论】:

      【解决方案2】:

      如果您只需要初始化一次缓存,Alexandr 提供了一个很好且简单的解决方案。

      如果需要更复杂的同步逻辑,原子缓存操作(PutIfAbsentReplace)通常可以代替锁。例如,我们可以有一个特殊的缓存来跟踪其他缓存的状态:

              var statusCache = Client.GetOrCreateCache<string, string>("status");
              if (statusCache.PutIfAbsent("cache-name", "created"))
              {
                  // Just created, add data
                  ...
                  //
                  statusCache.Put("cache-name", "populated");
              }
              else
              {
                  // Already exists, wait for data
                  while (statusCache["cache-name"] != "populated")
                      Thread.Sleep(1000);
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-20
        • 1970-01-01
        • 1970-01-01
        • 2020-06-21
        • 2020-02-14
        • 2019-11-09
        • 2021-10-04
        • 2021-09-22
        相关资源
        最近更新 更多