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