Google App Engine에서 High-CPU 요청을 어떻게 분류합니까?
-
03-07-2019 - |
문제
다른 무엇을 해야하는지 알아낼 수없는 요청의 예를 제시하려면 다음과 같습니다.
응용 프로그램은 a입니다 볼링 점수/통계 추적기. 누군가가 고급 모드에서 점수를 입력하면 많은 통계가 계산되고 점수가 계산됩니다. 데이터는 다음과 같이 모델링됩니다.
게임 - 이름, 사용자, 볼링 골목에 대한 참조, 스코어 프레임 - 각 볼에 대한 핀 폴, 각 공에 핀이 쓰러진 부울 목록, 공의 경로에 대한 정보 (Stance, Target, 실제로 어디로 갔다. ), 해당 프레임 등의 점수 등 Gamestats- 게임 그룹 전체에 걸쳐 통계 디스플레이에 필요에 따라 다른 게임 통계와 병합 될 수 있도록 전체 게임에 대한 통계를 계산했습니다.
실제로이 정보의 예를 찾을 수 있습니다. 여기.
게임이 완료되고 프레임이 업데이트되면 게임, 프레임, 모든 프레임 이후의 프레임 및 아마도 일부 (점수가 올바른지 확인하기 위해) 및 통계를 업데이트해야합니다. 이 작업은 항상 CPU 모니터에 표시됩니다. 게임이 완료되지 않았고 통계를 계산할 필요가 없더라도, 사용자에게 실시간 진행 상황을 보여주기 위해 점수와 업데이트가 필요하므로 이들도 신고됩니다. 이 핸들러의 평균 CPU 시간은 7000mcycles 이상이며 뷰도 표시되지 않습니다. 대부분의 사람들은 시리즈 당 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)
해결책
몇 가지 제안 :
- 프레임 통계를 각각의 엔티티를 갖지 않고 게임과 동일한 엔터티의 일부로 저장할 수 있으며, 각 반의 끝에 서있는 핀에 대한 비트 필드 (정수에 저장)로 저장함으로써. 예를 들어 프레임. 이 구현 방법에 대한 자세한 내용을 원하시면 알려주십시오.
- 실패하면 Fetch에서 더 상호 관련된 통계를 계산할 수 있습니다. 예를 들어, 전체 게임을 한 번에로드 한 경우 점수를 계산하면 간단해야합니다. 즉, 모든 요청에서 여러 프레임을 업데이트하지 않아도됩니다.
- 데이터 모델을 보여 주면 더 많은 도움이 될 수 있습니다. :)