3

我正在使用 Google App Engine 编写聊天应用程序。我想记录聊天记录。不幸的是,Google App Engine 数据存储区只允许您每秒写入一次。为了解决这个限制,我正在考虑使用内存缓存来缓冲写入。为了确保不丢失数据,我需要定期将数据从 memcache 推送到数据存储中。

有没有办法在 Google App 上安排这样的工作。引擎?还是我以完全错误的方式解决这个问题?

我正在使用 API 的 Python 版本,因此首选 Python 解决方案,但我对 Java 非常了解,可以将 Java 解决方案翻译成 Python。

4

5 回答 5

2

听起来像是错误的方式,因为您有丢失 memcache 数据的风险。

您可以每秒写入一个实体组一次。

您可以非常快速地编写单独的实体组。因此,这实际上取决于您如何构建数据。例如,如果您将整个聊天记录保存在一个实体中,则您每秒只能编写一次该聊天记录。而且您将被限制为 1MB。

您应该在聊天中为每条消息编写一个单独的实体,您可以非常非常快速地编写,但您需要设计一种方法将所有消息拉到一起,以便记录日志。

编辑我同意 Peter Knego 的观点,即每条消息使用一个实体的成本会变得太昂贵。他的后端建议也很不错,尽管如果您的应用程序很受欢迎,后端的扩展性就不会那么好。

我试图避免分片,但我认为这是必要的。如果您不熟悉分片,请阅读以下内容:https ://developers.google.com/appengine/articles/sharding_counters

分片将是为对话中的所有消息编写一个实体与每条消息一个实体之间的中间体。您将在多个实体之间随机拆分消息。例如,如果您将消息保存在 3 个实体中,则可以写入 5x/秒(我怀疑大多数人类对话会比这更快)。

在获取时,您需要抓取 3 个实体,并按时间顺序合并消息。这将为您节省很多成本。但是您需要编写代码来进行合并。

另一个好处是您的对话限制现在是 3MB 而不是 1MB。

于 2012-04-17T03:48:40.390 回答
2

要绕过实体组的写入/更新限制(请注意,没有父级的实体是他们自己的实体组),您可以为每条聊天消息创建一个新实体,并在其中保留一个属性来引用他们所属的聊天。

然后,您将通过查询找到属于某个聊天的所有聊天消息。但这会非常低效,因为您需要为每个用户查询每条新消息。

因此,请遵循上述建议,但还要执行以下操作:

  1. 查看后端。这是永远在线的实例,您可以在其中聚合内存中的聊天消息(并立即/定期将它们刷新到数据存储区)。当用户请求最新的聊天消息时,您已经将它们保存在内存中并会立即提供它们(与使用 Datastore 相比节省时间和成本)。请注意,后端并非 100% 可靠,它们可能会不时出现故障 - 相应地调整聊天消息刷新到数据存储。

  2. 查看频道 API。这将允许您在有新的聊天消息时通知用户。这样,您就可以避免轮询新的聊天消息并减少数量或请求。

于 2012-04-17T08:43:16.110 回答
1

为什么不使用拉任务?如果您对任务队列不够熟悉,我强烈推荐这个 Google 视频。前 15 分钟将涵盖可能适用于您的情况的拉取队列信息。任何涉及每条消息更新的事情都可能会变得非常昂贵:数据库操作,如果您涉及任何索引,这将大大加剧。视频链接: https ://www.youtube.com/watch?v=AM0ZPO7-lcE&feature=player_embedded

I would simply set up my chat entity when users initiate it in the on-line handler, passing back the entity id to the chat parties. Send the id+message to your pull queue, and serialize the messages within the chat entity's TextProperty. You wont likely schedule the pull queue cron more often than once per second, so that avoids your entity update limitation. Most importantly: your database ops will be greatly reduced.

于 2012-04-17T16:06:45.957 回答
0

我认为您可以创建将保留数据的任务。这样做的好处是,与 memcached 不同,任务是持久化的,因此不会丢失任何聊天记录。

当有新的聊天进来时,创建一个任务来保存聊天数据。在任务处理程序中执行持久化。您可以将任务队列配置为每秒拉 1 次(或稍慢),并将任务中保存的每一位聊天数据保存在临时表中(在不同的实体组中),并且每个任务都拉临时表中所有未保存的聊天,将它们保存到聊天实体,然后将它们从临时表中删除。

于 2012-04-17T09:50:02.687 回答
0

我认为您可以将聊天会话用作实体组并保存聊天消息。
这个每秒一次的限制不是现实,你可以以更高的速度更新/保存,我一直在这样做,我对此没有任何问题。memcache 是易失的,对于您想要做的事情来说是错误的选择。如果您开始遇到写入速率问题,您可以开始设置任务以保存数据。

于 2012-04-17T12:42:28.747 回答