我正在为自己的游戏开发高分Web服务,并且该服务正在Google App Engine上运行。

我的游戏有5个困难,所以我最初有5个板,每个板都有条目(player_login,得分和时间)。如果玩家提交的分数低于先前的分数,则将其解雇,因此每个玩家仅保留最高分数。

但是为了增加更多乐趣,我决定添加每日/每周/每月/每年的高分表。因此,我为每个难度创建了5个板,使其成为25个板。提交分数后,会将其保存到每个木板中,并且应该在每天/每周/每月/每年清除这些木板。

这是通过调用cron作业并从特定板卡删除所有条目来发生的。

问题来了:从数据存储中删除条目似乎很慢。从我的测试每日清理看来,删除单个条目大约需要200毫秒。

在最坏的情况下,如果该游戏非常受欢迎并且拥有10万名玩家,并且每个人在年度董事会中都有一个条目,那么这将花费100 000 * 0.012秒= 12000秒( 3小时!!)清除该木板。我认为我们可以在App Engine中进行长达30秒的工作,因此这是行不通的。

我正在使用following code (thanks to Nick Johnson)删除:

q = Score.all(keys_only=True).filter('b = ',boardToClear)
results = q.fetch(500)
  while results:
    self.response.out.write("deleting one batch;")
    db.delete(results)
    q = Score.all(keys_only=True).filter('b = ',boardToClear).with_cursor(q.cursor())
    results = q.fetch(500)

您建议我如何处理这个问题?

我想到的一种方法是使用任务队列并删除比每个板所允许的更旧的分数,即已过期但数量较少的分数。这样,我就不会达到一项任务的CPU限制,但是清理不会(几乎)是瞬时的,因此我的12000秒长的清理工作将分为1200个任务,每个任务约10秒。

但是我认为我做错了什么,在关系数据库中完成这种操作会更快。我对数据存储和评分的方法可能出了问题,因为它被锁定在RDBMS思维方式中。

最佳答案

首先,一些小建议:

  • 即使在批量处理中删除项目,删除每个项目也要花费200毫秒吗?最快的删除方法应该是执行keys_only查询,然后一次在整个键列表上调用db.delete()
  • 1.4.0开始,最近的30秒限制已放宽到10分钟以用于后台工作(例如您正在考虑的cron作业或队列任务)。

  • 但是,这些可能无法从根本上解决您的问题。我认为无法解决以下事实:删除大量记录(例如成千上万)将花费一些时间。我不确定这对您的用例来说是一个大问题,因为我可以看到一些有用的技术。
  • 如您建议的那样,使用任务队列将长时间运行的任务拆分为几个较小的任务。您的用例(删除大量与特定查询匹配的项目)非常适合执行map-reduce任务。尼克·约翰逊(Nick Johnson)的blog post on the Mapper API可能对您非常有帮助(因此您不必自己编写所有任务管理代码)。
  • 是否需要立即删除所有过期的板子条目?如果您有一个列出特定条目算入哪个星期,月份或年份的字段,则可以在该字段上建立索引,然后仅在可见的页首横幅上显示当前月份的条目。 (毕竟磁盘空间很便宜。)然后,如果您想缓慢地(例如花费数小时而不是毫秒)删除过时的数据,则可以在后台执行此操作,而不会在您的数据上留下任何不正确的数据。排行榜。
  • 关于google-app-engine - 如何处理App Engine数据存储区上的每日/每周/每月董事会?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4523501/

    10-09 08:21
    查看更多