在Google App Engine上同步Memcache和Datastore

时间:2012-04-17 03:20:55

标签: python google-app-engine memcached google-cloud-datastore

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

有没有办法在Google App上安排这样的工作。发动机?或者我是以完全错误的方式解决这个问题?

我正在使用API​​的Python版本,因此首选Python解决方案,但我非常了解Java,以便将Java解决方案转换为Python。

5 个答案:

答案 0 :(得分:2)

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

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

您可以非常快速地编写单独的实体组。所以这取决于你如何构建数据。例如,如果您在一个实体中保留整个聊天,则每秒只能编写一次聊天。你只能限制在1MB。

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

编辑我同意Peter Knego的观点,即每封邮件使用一个实体的成本会过于昂贵。他的后端建议也很不错,但如果你的应用程序很受欢迎,那么后端就不能很好地扩展。

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

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

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

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

答案 1 :(得分:2)

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

然后,您可以通过查询找到属于聊天的所有聊天消息。但这样效率非常低,因为您需要为每个新消息对每个用户进行查询。

请按照上述建议,但另外做:

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

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

答案 2 :(得分:1)

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

当用户在在线处理程序中启动聊天实体时,我会设置我的聊天实体,将实体ID传回聊天方。将id +消息发送到您的拉取队列,并序列化聊天实体的TextProperty中的消息。您不可能更频繁地调度拉队列cron,而不是每秒一次,这样可以避免实体更新限制。最重要的是:您的数据库操作将大大减少。

答案 3 :(得分:0)

我认为您可以创建将持久存储数据的任务。这具有以下优点:与memcached不同,任务是持久的,因此不会丢失聊天。

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

答案 4 :(得分:0)

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