【问题标题】:Best approach for caching lists of objects in memcache在 memcache 中缓存对象列表的最佳方法
【发布时间】:2016-05-06 11:47:17
【问题描述】:

我们的 Google AppEngine Java 应用程序涉及缓存从服务器请求信息的最近用户。

当前可行的解决方案是我们将用户信息存储在一个列表中,然后将其缓存。

当我们需要最近的用户时,我们只需从该列表中获取一个。

最近用户的列表对我们的应用程序运行并不重要,如果它从缓存中删除,它只是随着用户继续从服务器请求而重建。

我想知道的是:我能以更好的方式做到这一点吗?

使用当前的方法,我们只能存储一定数量的用户,然后列表变大以供 memcache 使用(我们目前将列表限制为 1000,并在插入新的时删除最旧的用户)。此外,列表将需要非常快速地更新,这涉及从 memcache 中检索完整列表以添加单个用户。

将每个用户分别存储在缓存中对我们有利,因为我们要求最近的用户在 30 分钟后过期。目前这是一项手动任务,我们会确保列表中不包含过期用户。

这种情况的最佳方法是什么?如果将用户单独存储在缓存中,那么跟踪用户以便我们检索它的最佳方法是什么?

【问题讨论】:

  • 用户信息很基础,目前连实体都没有。该列表是一个简单的 hashmap 列表,其中一个 hashmap 代表一个用户。 hashmap 包含用户性别、语言、插入时间戳和用户 iOS 推送通知标识符是否存在。
  • HashMap 听起来像是错误的数据类型。 HashMap 只对大量的键值对有效。我只会在内存缓存中存储一​​个“用户”实体。

标签: google-app-engine caching memcached


【解决方案1】:

您可以在内存缓存列表中只保留“指针”,您可以使用这些“指针”来构建单独的内存缓存键,以访问单独存储在内存缓存中的用户实体。这使得列表的 memcache 大小占用空间更小且易于处理。

如果用户实体有父实体,那么指针必须是它们的键,它们是唯一的,因此它们也可以用作内存缓存键(如果需要,它们的 urlsafe 版本)。

但是,如果用户实体没有父实体(即它们是实体组中的根实体),那么您可以使用它们的数据存储键 ID 作为指针 - 通常比键短。更好的是,如果 ID 是数字 ID,您甚至可以将它们存储为数字,而不是字符串。这些实体的 ID 是唯一的,但它们的唯一性可能不足以用作内存缓存键,您可能需要添加前缀/后缀以使相应的内存缓存键唯一(对您的应用程序而言)。

当您需要用户实体数据时,您首先从列表中获取“指针”,构建用户实体内存缓存键并使用该键检索实体。

当然,这假设您确实有理由保留该列表。如果列表本身不是强制性的,那么您只需要获取每个实体的(唯一)memcache 密钥的方法。

【讨论】:

  • 谢谢。在列表中使用指针而不是实体(或在我的情况下为 hashmap)是一个好主意,但对我来说唯一的好处是我将能够在列表中存储更多内容。我的个人缓存用户将在 30 分钟后过期,在列表中留下指向不存在的对象的指针..
  • 因此我的最后一段:你真的需要一个列表还是列表只是现有缓存解决方案的产物?您是否需要知道在过去 30 分钟内究竟是哪些用户从应用程序请求信息(这可能会解释该列表),或者您只想能够使用(最多 30 分钟)缓存的用户信息而不是数据存储信息(您可以在没有列表的情况下执行此操作)?
【解决方案2】:

如果你使用NDB caching,它会为你处理memcache。只需使用ndb.Key(Model, id).get()Model.get_by_id(id) 请求具有密钥的用户,其中id 是用户ID。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多