У меня немного странная проблема. У меня есть модуль, работающий на gae, который помещает множество небольших задач в очередь задач по умолчанию. Задачи обращаются к одному и тому же модулю ndb. Каждая задача получает доступ к набору данных из нескольких разных таблиц, а затем вызывает put
.
Первые несколько задач работают нормально, но со временем я начинаю получать их на последнем put
:
suspended generator _put_tasklet(context.py:358) raised TransactionFailedError(too much contention on these datastore entities. please try again.)
Поэтому я обернул пут попыткой и установил рандомизированный тайм-аут, чтобы он повторил попытку пару раз. Это немного смягчило проблему, просто это происходит позже.
Вот некоторый псевдокод для моей задачи:
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)
Без использования try_put
очередь проходит около 30% пути, пока не перестанет работать. С try_put он увеличивается, например, на 60%.
Может ли быть так, что задача удерживает соединения ndb после того, как она каким-то образом завершилась? Я не использую явным образом транзакции.
РЕДАКТИРОВАТЬ:
кажется, есть некоторая путаница в том, что я спрашиваю. Возникает вопрос: почему со временем конкуренция за ndb становится все хуже. У меня одновременно выполняется множество задач, и они обращаются к ndb таким образом, что это может вызвать конкуренцию. Если конкуренция обнаружена, то происходит случайная повторная попытка по времени, и это прекрасно устраняет конкуренцию. В течение некоторого времени. Задачи продолжают выполняться и завершаться, и чем больше успешно возвращается, тем больше конфликтов. Хотя процессы, использующие оспариваемые данные, должны быть завершены. Что-то происходит, что держит дескрипторы хранилища данных, чего не должно быть? В чем дело?
РЕДАКТИРОВАТЬ2:
Вот немного о ключевых структурах в игре:
Мои модели ndb находятся в иерархии, где у нас есть что-то вроде этого (направление стрелок указывает родительские дочерние отношения, то есть: тип имеет кучу дочерних экземпляров и т. д.)
Type->Instance->Position
Идентификаторы позиций ограничены несколькими разными именами, существует много тысяч экземпляров и не так много типов.
Я вычисляю кучу позиций, а затем делаю try_put_multi (очевидным образом похож на try_put) и получаю конкуренцию. Довольно скоро я снова запущу код и получу полную трассировку для включения сюда.
Instance
s до несколькихType
s =› большие группы сущностей, каждая группа поддерживает максимум ~ 1 запись в секунду. Какова частота задач, обновляющихInstance
s для одного и того же родителяType
(т. е. одной и той же группы)? У вас естьthreadsafe: true
в конфигурации.yaml
? - person Dan Cornilescu   schedule 01.03.2016