首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >谷歌应用引擎的全球领先地位

谷歌应用引擎的全球领先地位
EN

Stack Overflow用户
提问于 2014-02-24 04:43:32
回答 3查看 946关注 0票数 3

我想为一款手机游戏构建一个后端,其中包括一个面向所有玩家的“实时”全球领先板,用于使用Google (Python)进行持续一定时间的活动。

一个典型的用法如下:-用户开始并完成一场战斗,获得点(2-5分钟的战斗)-积分在玩家的帐户中积累在事件的持续时间。-玩家可以随时检查主板。-领头羊将返回前10名球员,以及5名球员仅仅在和低于球员的分数。

现在,在实时方面没有真正的限制,板可以每30秒更新一次,每小时更新一次。我希望它是尽可能“快”,而不太贵。

由于我对GAE不太熟悉,所以我想到了这个解决方案:

  • 每个播放器实体都有一个event_points属性
  • 使用Cron作业,在一个正常的间隔内,对所有得分不是零的玩家的数据存储进行查询。对查询进行排序。
  • cron作业然后遍历查询结果,在每个Player实体中返回排名。

当我想到这个解决方案时,感觉很“蛮力”。

此解决方案的问题在于所有实体的读和写成本。如果我们以50K活动用户结束,这将意味着对50K+1读取的排序查询,以及50k+1定期写入,这可能非常昂贵(取决于间隔)。

我知道memcache可以阻止一些读和写,但是如果有些实体不在memcache中,那么查询它有意义吗?而且,我也读过,memcache无论如何都可以被刷新,所以除非有一种方法可以廉价地“备份”它,否则它似乎是一个危险的用途,因为数据是相对重要的。

有更简单的方法来解决这个问题吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-24 06:41:47

你不需要50,000读或5万写。解决方案是在points属性上设置排序顺序。每次更新它时,数据存储都会自动更新它的顺序,这意味着除了points属性之外,您不需要级别属性。因此,你不需要一份工作。

然后,当您需要检索一个领导板时,您需要运行两个查询:一个是针对与用户的点数多或相等的6个实体,另一个是针对较少或相同点数的6个实体。合并结果,这就是您要向用户显示的内容。

至于您的前10位查询,您可能希望将其结果放在Memcache中,其过期时间为5分钟。当您需要它时,首先检查Memcache。如果未找到,请运行查询并更新Memcache。

编辑:

若要澄清查询部分,请执行以下操作。您需要设置排序顺序和不等式筛选器的正确组合,以获得所需的结果。根据App文档,查询按以下顺序执行:

  1. 标识与查询的种类、筛选属性、筛选运算符和排序顺序相对应的索引。
  2. 从索引开始扫描到满足所有查询筛选条件的第一个实体。
  3. 继续扫描索引,依次返回每个实体,直到遇到不满足筛选条件的实体,或到达索引的末尾,或已收集查询请求的最大结果数。

因此,对于一个查询,您需要将升序顺序与GREATER_THAN_OR_EQUAL过滤器相结合,对于另一个查询,则需要将降序顺序与LESS_THAN_OR_EQUAL过滤器相结合。在这两种情况下,您都将检索结果的限制设置为6。

还要注意:您将限制在6个实体,因为这两个查询都将返回用户本身。您可以添加另一个过滤器(userId NOT_EQUAL到您的用户id),但是我不推荐它--成本不值得节省。显然,不能对点使用大于/小于__过滤器,因为许多用户可能有相同的点数。

票数 2
EN

Stack Overflow用户

发布于 2014-08-19 18:07:14

下面是一个Google 文章,它解释了类似的问题以及使用Google代码阻塞排名库的解决方案。对这个库的进一步帮助和扩展可以在Google 论坛中讨论。

这个库基本上创建了一个N叉树,每个节点都包含特定范围内分数的计数。得分范围被进一步划分,一直到叶节点,在那里它是一个单一的分数。树遍历(O log(n) )可用于查找得分高于特定分数的玩家数量。这是球员的排名。它还建议将分数提交请求聚合到一个拉任务队列中,然后在后端的后台线程中以批处理方式处理它们。

票数 1
EN

Stack Overflow用户

发布于 2014-02-24 05:01:14

这是否简单是值得商榷的。

我认为排名不仅仅是排序积分的问题,在这种情况下,这只是一个简单的查询。我的排名涉及到其他因素,而不仅仅是目前的分数。

我会考虑为用户每次更新点数(实际上是一个队列)编写一个事件记录。任务运行收集所有当前事件记录,此外,还维护一组表示领导板顶部的记录。根据传入的事件记录调整这组记录。一旦处理,丢弃事件记录。这将限制您在小时间窗口中只对活动事件进行读写。领导委员会可能是一个单一的实体,由密钥获取并缓存。

我假设您可能有不同的排名方案,如当前的活动等级(针对当前的7天),和所有的时间级别。(一段时间不打球的球员)。

当玩家查看他们的排名时,您可以使用两个简单的查询-- Players.query(Players.score > somescore).fetch(5)Players.query(Players.score < somescore).fetch(5) --这不应该花费太多,您可以缓存它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21979038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档