J'ai des problèmes de contention dans Google App Engine et j'essaie de comprendre ce qui se passe.Problèmes de contention dans Google App Engine
J'ai un gestionnaire de requêtes annotée avec:
@ndb.transactional(xg=True, retries=5)
..et dans ce code, je vais chercher des choses, mettre à jour quelques autres, etc., mais parfois une erreur comme celle-ci vient dans le journal lors d'une demande:
16:06:20.930 suspended generator _get_tasklet(context.py:329) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
16:06:20.930 suspended generator get(context.py:744) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
16:06:20.930 suspended generator get(context.py:744) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
16:06:20.936 suspended generator transaction(context.py:1004) raised TransactionFailedError(too much contention on these datastore entities. please try again. entity group key: app: "s~my-appname"
path <
Element {
type: "PlayerGameStates"
name: "hannes2"
}
>
)
.. suivi d'une trace de pile. Je peux mettre à jour avec toute la trace de la pile si nécessaire, mais c'est assez long.
Je ne comprends pas pourquoi cela arrive. En regardant la ligne dans mon code là l'exception vient, je cours get_by_id
sur une entité totalement différente (ronde). Le "PlayerGameStates", nom "hannes2" qui est mentionné dans les messages d'erreur est le parent d'une autre entité GameState, qui a été get_async
: édité à partir de la base de données quelques lignes plus tôt;
# GameState is read by get_async
gamestate_future = GameState.get_by_id_async(id, ndb.Key('PlayerGameStates', player_key))
...
gamestate = gamestate_future.get_result()
...
Bizarre (?) Chose est, il n'y a pas d'écritures dans la banque de données se produisant pour cette entité. Ma compréhension est que les erreurs de contention peuvent venir si la même entité est mise à jour en même temps, ou peut-être si trop d'écritures se produisent, dans un court laps de temps ..
Mais peut-il se produire lors de la lecture des entités aussi? ("Générateur suspendu get .." ??) Et, est-ce que cela se passe après les tentatives de 5 ndb.transaction ..? Je ne vois rien dans le journal qui indique que des tentatives ont été faites.
Toute aide est grandement appréciée.
Je regarderais votre structure de clé. La contention n'est pas seulement au niveau de l'entité. Vous devez également examiner les parents. Regardez la portée de vos groupes d'entités afin de comprendre pourquoi vous avez des conflits. –
Merci. J'ai essayé de garder les petits groupes d'entités, et d'éviter les conflits - mais j'examinerai plus. Dans ce cas, un conflit s'est produit dans le groupe d'entités avec le parent 'ndb.Key (" PlayerGameStates "," hannes2 ")', n'est-ce pas? Je ne comprends toujours pas pourquoi ** lire ** déclenche une exception/contention? Où puis-je lire plus à ce sujet ..? – boffman
@TimHoffman Ok, je l'ai trouvé dans la [Documentation sur les transactions inter-groupes] (https://cloud.google.com/appengine/docs/python/datastore/#Python_Cross_group_transactions): "Remarque: Première lecture d'une entité Un groupe dans une transaction XG peut déclencher une exception TransactionFailedError en cas de conflit avec d'autres transactions accédant à ce même groupe d'entités, ce qui signifie que même une transaction XG effectuant uniquement des lectures peut échouer avec une exception de concurrence. " – boffman