【问题标题】:Cache the DTO or cache data from the expensive resource缓存 DTO 或缓存来自昂贵资源的数据
【发布时间】:2016-01-15 00:52:09
【问题描述】:

我有一个返回 DTO 的 WebService。 Web 服务从昂贵的资源中获取数据以填充 DTO。在这个简单的例子中,几个 WebService 方法可能会命中同一个 ExpensiveResourceProvider 方法。执行缓存以最大化缓存命中率的最佳位置在哪里?在网络服务还是在 ExpensiveResourceProvider?我应该注意,ExpensiveResourceProvider 中的一些数据经常更改,不应长时间缓存。

public class MyWebService : System.Web.Services.WebService
{
    public MyDTO GetObject1And2()
    {
        MyDTO dto12 = HttpRuntime.Cache.Get("dto12") as MyDTO;
        if(dto12 == null){
            dto12 = new MyDTO();
            dto12.Object1 = ExpensiveResourceProvider.GetObject1();
            dto12.Object2 = ExpensiveResourceProvider.GetObject2();
            HttpRuntime.Cache.Insert("dto12", dto12);
        }
        return dto12;
    }
    public MyDTO GetObject2And3()
    {
        MyDTO dto23 = HttpRuntime.Cache.Get("dto23") as MyDTO;
        if (dto23 == null)
        {
            dto23 = new MyDTO();
            dto23.Object2 = ExpensiveResourceProvider.GetObject2();
            dto23.Object3 = ExpensiveResourceProvider.GetObject3();
            HttpRuntime.Cache.Insert("dto23", dto23);
        }
        return dto23;
    }
    public MyDTO GetObject1And3()
    {
        MyDTO dto13 = HttpRuntime.Cache.Get("dto13") as MyDTO;
        if (dto13 == null)
        {
            dto13 = new MyDTO();
            dto13.Object1 = ExpensiveResourceProvider.GetObject1();
            dto13.Object3 = ExpensiveResourceProvider.GetObject3();
            HttpRuntime.Cache.Insert("dto13", dto13);
        }
        return dto13;
    }
}    
public class ExpensiveResourceProvider
{
    public static object GetObject1() 
    {
        object obj1 = HttpRuntime.Cache.Get("object1") as object;
        if(obj1 == null){
            obj1 = new object();
            HttpRuntime.Cache.Insert("object1", obj1);
        }
        return obj1; 
    }
    public static object GetObject2() 
    {
        object obj2 = HttpRuntime.Cache.Get("object2") as object;
        if (obj2 == null)
        {
            obj2 = new object();
            HttpRuntime.Cache.Insert("object2", obj2);
        }
        return obj2;
    }
    public static object GetObject3()
    {
        object obj3 = HttpRuntime.Cache.Get("object3") as object;
        if (obj3 == null)
        {
            obj3 = new object();
            HttpRuntime.Cache.Insert("object3", obj3);
        }
        return obj3;
    }
}
public class MyDTO
{
    public object Object1 { get; set; }
    public object Object2 { get; set; }
    public object Object3 { get; set; }
}

【问题讨论】:

    标签: asp.net caching service


    【解决方案1】:

    数据的波动性是决定将其缓存到何处的关键。根据您的缓存机制,您将有不同的方式来通知您的数据已过时并且是时候刷新它了。假设您的缓存机制提供回调委托,在这种情况下,您的委托应该与通常填充缓存的代码位于同一层(最好是填充缓存的 same 代码开始)。话虽如此,您的缓存似乎最好留给您的 ExpensiveResourceProvider。

    【讨论】:

    • 陈旧数据在一定程度上是可以容忍的,所以我没有使用任何回调通知。通常,我只会设置 90 秒的绝对到期时间。之后的下一次点击将强制刷新该数据。
    【解决方案2】:

    回到缓存基础,你不应该考虑同时做出两个不同层缓存策略的决策,它们是两个不同的决策。

    对于消费者和服务的每一层,如果您确定消费者在数据有效期内有很高机会请求相同信息的使用模式,则将其缓存。如果使用模式在数据有效期内只有远程机会访问同一条数据,不要浪费内存和cpu缓存。

    如果您的 Web 服务层已经缓存以解决最终的消费者使用模式,这意味着您的资源层不应在数据有效期内再次调用。

    但是,您的 Web 服务方法似乎不是一个好的设计,它会相互重叠信息。我认为您的问题不是缓存问题,而是您的 DTO 对象和 WS 方法签名设计关于如何正确分组数据的问题。

    但在某些情况下,假设您的每个 Web 服务方法都需要引用资源层的引用表。此时,你可以决定在资源层缓存它。

    我的两分钱...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-10
      • 2015-11-15
      • 2011-03-21
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多