【问题标题】:Match Making using GAE + ndb使用 GAE + ndb 进行牵线搭桥
【发布时间】:2016-10-06 15:02:29
【问题描述】:

我有一个游戏,其中用户联系服务器以查找想要玩游戏的同级别用户。这是游戏请求的基本架构。

我正在使用ndb 在 Google DataStore 中为每个用户级别存储一个等待队列。

我通过它们的键访问这些队列以确保强一致性(根据this article)。实体使用重复的(列表)LocalStructuredProperty 存储在队列中。

问题:

  1. 一个实体被从等待队列中删除,因为它与一个请求相匹配。事务已提交但尚未应用。同一实体与另一个请求匹配并被删除。这会引发错误吗?
  2. 这些高度一致的访问被限制为 ~1 写入/秒。有没有更好的架构可以消除这种限制?

我为后一个问题考虑的一件事是维护多个队列(其数量随需求而增长和缩小)。

【问题讨论】:

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


    【解决方案1】:

    不确定您的第一个问题,但您可以在事务中使用 sleep 语句来模拟它。

    对于您的第二个问题,您可以使用另一种架构。如果等待队列的持续时间相对较短(几分钟而不是几小时),您可能需要使用 memcache。这将比写入磁盘快得多,并且您可以避免处理一致性问题。

    【讨论】:

    • 是的,希望有人知道这个理论:)。担心memcache getting dropped。知道这种情况多久发生一次吗?
    • 我不知道删除 memcache 的频率,我知道这取决于 memcache 的总负载/需求(包括其他用户)。您可以通过写入 NDB 和 memcache 来管理它。如果您的队列在键中没有任何祖先,则不应受到 1 write/sec 约束的限制,它仅适用于父键。
    【解决方案2】:

    1.- 如果您在事务中进行实体获取和发布,则同一实体无法匹配到游戏中,因此不会出错且保持一致。

    2.- 每秒 1 次写入是同一实体组内事务的限制。如果需要更多,可以对队列实体进行分片。

    您可以使用专用的 memcache 或 redis 实例来避免争用。这比数据存储快得多。

    看看这些家伙如何使用树节点进行匹配: https://www.youtube.com/watch?v=9nWyWwY2Onc

    【讨论】:

    • 担心memcache getting dropped。知道这种情况多久发生一次吗?
    • 该视频中的匹配系统(使用玩家级别的桶)看起来与问题中提出的相似(每个级别的队列不同)。有什么我想念的吗?
    • Memcache 在填满时丢弃键。您无法控制它,除非您只为您付费购买专用服务器。
    • 视频中的系统不同,因为它没有使用重复的属性来存储实际的队列。
    • 根据我的经验,为专用的 memcache 付费会导致丢弃的项目要少得多
    猜你喜欢
    • 2014-05-28
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多