J'ai un problème étrange. J'ai un module en cours d'exécution sur gae qui met beaucoup de petites tâches sur la file d'attente de tâches par défaut. Les tâches accèdent au même module ndb. Chaque tâche accède à un tas de données à partir de quelques tables différentes puis appelle put
.La contention de données ndb s'aggrave
Les premières tâches fonctionnent bien, mais que le temps continue, je commence à obtenir ces derniers sur le put
final:
suspended generator _put_tasklet(context.py:358) raised TransactionFailedError(too much contention on these datastore entities. please try again.)
J'Enveloppez la vente avec un essai et mis dans un délai aléatoire il retente quelques fois. Cela a atténué un peu le problème, cela arrive plus tard.
Voici quelques pseudo-code pour ma tâche:
def my_task(request):
stuff = get_ndb_instances() #this accessed a few things from different tables
better_stuff = process(ndb_instances) #pretty much just a summation
try_put(better_stuff)
return {'status':'Groovy'}
def try_put(oInstance,iCountdown=10):
if iCountdown<1:
return oInstance.put()
try:
return oInstance.put()
except:
import time
import random
logger.info("sleeping")
time.sleep(random.random()*20)
return oInstance.try_put(iCountdown-1)
Sans utiliser try_put
la file d'attente obtient environ 30% du chemin à travers jusqu'à ce qu'il cesse de fonctionner. Avec le try_put, il va plus loin, comme 60%.
Est-ce qu'une tâche est en attente sur les connexions ndb après la fin de la connexion? Je n'utilise pas explicitement les transactions.
EDIT:
il semble y avoir une certaine confusion sur ce que je demande. La question est: pourquoi les conflits ndb s'aggravent avec le temps. J'ai beaucoup de tâches en cours d'exécution simultanément et ils accèdent au ndb d'une manière qui peut provoquer des conflits. Si la contention est détectée, une nouvelle tentative est effectuée, ce qui élimine parfaitement la contention. Pour un peu de temps. Les tâches continuent de s'exécuter et de s'exécuter et plus elles retournent avec succès, plus la contention est importante. Même si les processus utilisant les données contestées doivent être terminés. Y at-il quelque chose qui se passe sur les poignées de datastore qui ne devrait pas l'être? Que se passe-t-il?
EDIT2:
Voici un peu plus sur les structures clés en jeu:
Mes modèles NDB sont assis dans une hiérarchie où nous avons quelque chose comme ça (la direction des flèches spécifie les relations entre parents et enfants, à savoir: type a un tas d'instances d'enfants, etc.)
Type->Instance->Position
les ids des positions sont limitées à quelques noms différents, il y a plusieurs milliers de cas et pas beaucoup de types.
Je calcule un tas de Positions, puis fais un try_put_multi (similaire à try_put d'une manière évidente) et obtient des conflits. Je vais lancer le code très bientôt et obtenir une trace complète à inclure ici.
Avez-vous vraiment essayé/sauf? –
Quelle est la structure de clé utilisée, quel type d'erreur de contention obtenez-vous? –
Copie possible de ["Trop de contention" lors de la création d'une nouvelle entité dans le stock de données] (http://stackoverflow.com/questions/17308179/too-much-contention-when-creating-new-entity-in-datastore) –