首页 文章

如何向所有Google App Engine实例广播数据?

提问于
浏览
3

为简单起见,假设我的应用程序需要允许数千名用户查看聊天室的实时只读流 . 主机可以键入消息,但没有其他用户可以 - 他们只是实时查看主机键入的内容 . 想象一下,用户正在关注体育赛事的文字游戏 .

每个用户通过对GAE服务器的简单 /get-recent-messages 调用每秒轮询一次来检查新消息 . (在您提出要求之前,我相信使用Google的 Channels API会太昂贵 . )

考虑到这个应用程序同时被成千上万的用户使用,这意味着运行了数十到数百个GAE实例,我如何能够通过这些 /get-recent-messages 调用来返回延迟小于1000毫秒的最新聊天室消息,同时最大限度地减少服务器负载和GAE成本?

我有一些想法:

  • Store chat messages in datastore entities.

  • 显然这太慢而且昂贵,尤其是在使用查询/索引时

  • Store chat messages in memcache keys. 我想我会使用一个密钥来存储最近50条消息的密钥列表,然后再使用50个密钥,每条消息一个 .

  • 这会导致巨大的瓶颈,因为App Engine的memcache按密钥进行分片,因此所有500个实例都会不断地从相同的memcache密钥读取,从而读取相同的memcache服务器 .

  • Store chat messages in instance memory, backed by memcache. 当实例内存过时时,从memcache(比如#2)中拉出来 .

  • 当多个请求看到过时的实例内存缓存并同时从memcache中拉出时,这可能会导致昂贵的竞争条件 .

  • Use a background thread to update instance memory from memcache. 这可以使用在预热请求中启动的线程每个实例每秒运行一次 . 它会像#3一样工作,但只有一个线程拉而不是随机请求触发memcache读取 .

  • 我真的不知道这是否适合使用预热请求 .

  • Use Google's Pub/Sub service.

  • 我不知道这是如何工作的,似乎这个用例可能有点过分 .

  • Run a once-per-second cron job to pull from memcache. 除了不依赖后台线程外,这将是#4 .

  • 我需要每秒在每个实例上运行它 . 我不相信cron / taskqueue API有办法在所有活动实例上运行作业或任务 .

思考?

1 回答

  • 2

    你应该检查this video . 我会选择memcache / datastore版本和少量缓存(1-2秒),这样您就可以减少为流量提供服务所需的实例数量 . 如果您仍然需要100-500个实例来为您的流量提供服务,我仍然会选择memcache / datastore版本 . 如果memcache是你的瓶颈,请将它分成10个键 .

    另一种解决方案是使用Compute Engine和Web服务器,您可以通过套接字连接用户 . 您可以通过HTTP与计算实例通信,并将值存储在内存中或使用pull队列 .

    如果您确实需要与所有实例进行通信,请查看communicating between modules

    Pub / sub可能是您在发布新消息的实例与读取新消息的实例之间进行通信的一个很好的选择 . 从我在docs中读到的内容,你应该能够直接订阅你的用户到Pub / Sub(只拉你) .

相关问题