如何在Google App Engine上分解高CPU请求?

时间:2020-03-06 14:55:51  来源:igfitidea点击:

举一个我无法弄清楚还要做什么的请求示例:

该应用程序是保龄球得分/统计跟踪器。当某人以高级模式输入其分数时,将计算许多统计数据及其分数。数据建模为:

游戏成员,例如姓名,用户,对保龄球馆的参考,得分
每个球的帧落差,布尔值列表(每个球被击倒的布尔值列表),有关球的路径(姿势,目标,实际到达的位置)的信息,该帧的得分等
GameStats存储整个游戏的计算统计信息,并根据需要与其他游戏统计信息合并,以便在游戏组之间显示统计信息。

在实践中可以找到此信息的示例。

当游戏完成并更新了一个框架时,我必须更新游戏,该框架,其后的每个框架以及可能的之前的一些框架(以确保它们的分数正确)以及统计信息。此操作始终标记CPU监视器。即使游戏还没有完成,也不需要计算统计信息,也需要更新分数等以向用户显示实时进度,因此也会标记这些分数。该处理程序的平均CPU时间超过7000毫秒,甚至不显示视图。如果每个人都在赛道上实时输入分数,那么大多数人每个系列会打3到4场比赛,每2到4分钟大约要提出1个请求,但是如果他们都记下来并稍后输入,那么其中有30到40场比赛连续进行的请求。

根据要求,重要类的数据模型:

class Stats(db.Model):
  version = db.IntegerProperty(default=1)
  first_balls=db.IntegerProperty(default=0)
  pocket_tracked=db.IntegerProperty(default=0)
  pocket=db.IntegerProperty(default=0)
  strike=db.IntegerProperty(default=0)
  carry=db.IntegerProperty(default=0)
  double=db.IntegerProperty(default=0)
  double_tries=db.IntegerProperty(default=0)
  target_hit=db.IntegerProperty(default=0)
  target_missed_left=db.IntegerProperty(default=0)
  target_missed_right=db.IntegerProperty(default=0)
  target_missed=db.FloatProperty(default=0.0)
  first_count=db.IntegerProperty(default=0)
  first_count_miss=db.IntegerProperty(default=0)

  second_balls=db.IntegerProperty(default=0)
  spare=db.IntegerProperty(default=0)
  single=db.IntegerProperty(default=0)
  single_made=db.IntegerProperty(default=0)
  multi=db.IntegerProperty(default=0)
  multi_made=db.IntegerProperty(default=0)
  split=db.IntegerProperty(default=0)
  split_made=db.IntegerProperty(default=0)

class Game(db.Model):
  version = db.IntegerProperty(default=3)
  user = db.UserProperty(required=True)
  series = db.ReferenceProperty(Series)
  score = db.IntegerProperty()
  game_number = db.IntegerProperty()
  pair = db.StringProperty()
  notes = db.TextProperty()
  simple_entry_mode = db.BooleanProperty(default=False)
  stats = db.ReferenceProperty(Stats)
  complete = db.BooleanProperty(default=False)

class Frame(db.Model):
  version = db.IntegerProperty(default=1)
  user = db.UserProperty()
  game = db.ReferenceProperty(Game, required=True)
  frame_number = db.IntegerProperty(required=True)
  first_count = db.IntegerProperty(required=True)
  second_count = db.IntegerProperty()
  total_count = db.IntegerProperty()
  score = db.IntegerProperty()
  ball = db.ReferenceProperty(Ball)
  stance = db.FloatProperty()
  target = db.FloatProperty()
  actual = db.FloatProperty()
  slide = db.FloatProperty()
  breakpoint = db.FloatProperty()
  pocket = db.BooleanProperty()
  pocket_type = db.StringProperty()
  notes = db.TextProperty()
  first_pinfall = db.ListProperty(bool)
  second_pinfall = db.ListProperty(bool)
  split = db.BooleanProperty(default=False)

解决方案

一些建议:

  • 我们可以将帧的统计信息存储为与游戏相同的实体的一部分,而不是为每个实体拥有单独的实体,方法是将帧的统计信息存储为位于每个半部末尾的引脚的位域列表(以整数存储),例如框架。让我知道是否需要更多有关如何实现的详细信息。
  • 如果失败,则可以在获取时计算一些其他相互关联的统计信息。例如,如果我们一次加载了整个游戏,则到目前为止的分数计算应该很简单,这意味着我们可以避免在每次请求时都必须更新多个帧。
  • 如果我们向我们展示数据模型,我们将为我们提供更多帮助。 :)