【问题标题】:JSON Object Cache With Property Expiration For GraphQL Responses具有 GraphQL 响应的属性过期的 JSON 对象缓存
【发布时间】:2019-10-02 22:25:07
【问题描述】:

我创建了一个缓存 (nosql),它获取 graphQL json 对象并将它们展平。这意味着所有子对象都被引用替换并单独存储。例如给定以下输入:

{
    "users": [
         {"type": "user", "id": 1, "name": "bob"}, {"type": "user", "id": 1, "name": "bill"}
    ]
}

存储为:

{ 
    "users": ["ref-user-1", "ref-user-2"],
    "ref-user-1": {"type": "user", "id": 1, "name": "bob"},
    "ref-user-2": {"type": "user", "id": 1, "name": "bill"}
}

这种方法的好处是,如果另一个包含user-1 信息的请求,我们可以更新我们的本地数据存储。然后,如果通过 id 向用户发出请求,我们可能会获得所有必需的信息。

问题来自缓存失效。我们如何知道缓存条目是否是最新的?为了这篇文章,我们可以说一个对象是有效的,如果它的所有字段都在 2 小时内被缓存。如果另一个请求带有user-1,我们希望更新该请求返回的字段的本地时间戳。

如何以高效的方式保存每个字段的时间戳?

考虑的选项:

  1. 每个值都有自己的时间戳。所有查找都是 O(1),但我们会有大量重复的时间戳数据。

    "ref-user-1": {"type": "user", "id": {"val": 1, "ts": "1557941674"}, "name": {"val": "bob" "ts": "1557941674"}}

  2. 将属性时间戳存储为属性集,每组有一个时间戳。查找会很慢,但会减少数据。更新也可能很慢。如果我们可以将字段转换为哈希,并检查较大的哈希是否包含较小哈希中的所有字段,那就太好了。

    "ref-user-1": {"type": "user", "id": 1, "name": "bob", "field_sets": ["ts": "1557941674", "fields": ["id", "name"]] }

  3. 我没有考虑过的花哨的数据结构......

【问题讨论】:

    标签: algorithm caching data-structures hash graphql


    【解决方案1】:

    正如老笑话所说,“计算机科学中只有两个难题。命名、缓存失效和一个错误。”

    所以这是一个难题,应该很难。

    我建议重要的不是数据返回的时间,而是数据的缓存时间。否则,通常请求的数据可能会过时并无限期保留。 (看,我说过缓存失效很难!)

    这表明时间戳应该基于缓存最近更新的时间。因此,如果数据少于 1.5 小时,您可以只返回数据。如果它是 1.5-2 小时大,你掷硬币。 (随着翻转它的可能性增加)。如果年龄较大,您将其视为无效。这种策略使得数据很可能只被请求一次以进行刷新,即使它被非常活跃地访问。

    这种方法需要每个属性的时间戳。并允许知道它更改了其中一些数据的作业抢先使某些字段无效。当您去填充对象时,您知道发生了这种情况,因为存在对不存在的数据的引用,并且您知道需要刷新它。 (无论是在缓存层还是应用层处理刷新都是一个设计决策,可以采取任何一种方式。)

    【讨论】:

    • 我所说的“返回”是指由服务器返回,所以它是最近被缓存的。次要清洁工作的有趣方法。
    猜你喜欢
    • 2014-04-20
    • 2020-04-04
    • 2021-12-08
    • 1970-01-01
    • 2022-10-02
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    相关资源
    最近更新 更多