我想知道设计一个社交应用程序的最佳方式是什么,让成员可以使用 Google AppEngine 进行活动并跟踪其他成员的活动。

更具体地说,假设我们有这些实体:

  • 用户 谁有朋友
  • 活动 代表用户所做的操作(假设每个都有一个字符串消息和一个对其所有者用户的 ReferenceProperty,或者它可以通过 appengine 的密钥使用父关联)

困难的部分是关注您朋友的活动,这意味着汇总所有朋友的最新活动。通常,这将是“活动”表和您的好友列表之间的联接,但这在 appengine 上不是一个可行的设计,因为没有模拟它的联接需要启动 N 个查询(其中 N 是好友数量),然后在内存中合并 -非常昂贵,并且可能会超过请求期限......)

我目前正在考虑使用收件箱队列来实现这一点,其中创建新活动将触发后台进程,该进程会将新活动的密钥放入每个以下用户的“收件箱”中:

  • 获取“所有关注 X 的用户”是一个可能的应用引擎查询
  • 不是非常昂贵的批量输入到基本上存储(用户,活动键)元组的新“收件箱”实体中。

我很高兴听到对此设计的想法或替代建议等。

有帮助吗?

解决方案

看一眼 在 App Engine 上构建可扩展的复杂应用程序 (pdf),Brett Slatkin 在 Google I/O 上发表的精彩演讲。他解决了构建 Twitter 等可扩展消息服务的问题。

这是他的 解决方案 使用列表属性:

class Message(db.Model):
    sender = db.StringProperty()
    body = db.TextProperty()

class MessageIndex(db.Model):
    #parent = a message
    receivers = db.StringListProperty()

indexes = MessageIndex.all(keys_only = True).filter('receivers = ', user_id)
keys = [k.parent() for k in indexes)
messages = db.get(keys)

此仅键查询会查找接收者等于您指定的接收者的消息索引,而无需反序列化和序列化接收者列表。然后,您可以使用这些索引来仅获取您想要的消息。

这是 错误的方法 去做吧:

class Message(db.Model):
    sender = db.StringProperty()
    receivers = db.StringListProperty()
    body = db.TextProperty()

messages = Message.all().filter('receivers =', user_id)

这是低效的,因为查询必须解包查询返回的所有结果。因此,如果您返回 100 条消息,每个接收者列表中有 1,000 个用户,则必须反序列化 100,000 (100 x 1000) 个列表属性值。数据存储延迟和 CPU 成本太高。

一开始我对这一切感到非常困惑,所以我写了一篇 关于使用列表属性的简短教程. 。享受 :)

其他提示

我不知道是否是 最好的 为社交应用程序设计,但是 贾伊库 曾是 移植到 App Engine 当该公司被谷歌收购时,它是由它的原始创建者创建的,所以这应该是合理的。

参见 参考资料 部分 演员和老虎和熊,天哪!设计_funument.txt. 。实体定义在 常见/models.py 查询位于 通用/api.py.

罗伯特,关于您提出的解决方案:

messages = Message.query(Message.receivers == user_id).fetch(projection=[Message.body])

我认为 ndb.TextProperty“body”不能与投影一起使用,因为没有索引。投影仅支持索引属性。有效的解决方案是维护两个表:消息和消息索引。

我认为现在可以通过 NDB 中的新投影查询来解决这个问题。

class Message(ndb.Model):
    sender = ndb.StringProperty()
    receivers = ndb.StringProperty(repeated=True)
    body = ndb.TextProperty()

messages = Message.query(Message.receivers == user_id).fetch(projection=[Message.body])

现在您不必处理反序列化列表属性的昂贵成本。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top