Pull to refresh

GAE: batch put, распределение и некоторые обманные телодвижения

Reading time 2 min
Views 443
Непонятный заголовок, отсутствие картинки – вобщем топик в чисто маразматичном стиле.

Случилось как-то раз Емеле узнать откуда родом посетители его хомяка (утрирую), для чего Емеля обратился в maxmind с просьбой дать IP2City базу.

Вобщем-то начало какое-то умное…

Задача: Сделать определение города пользователя по IP для GAE приложения.

Первые проблемы:
— нельзя залить файл базы напрямую (ограничение 1мб/файл)
— ограниченные бесплатные ресурсы

и да, проблемы не последние.

Конечно, можно было поднять сервачек, залить базу на мускл, да или вообще использовать бинарную базу и питоновский IP, но не хотелось разводить зоопарк + ещё горка «НО», которые гораздо меньше.

Заливать 3,5 млн объектов в основное приложение не решился, на то есть причины:
— приложению самому нужны ресурсы
— нет взаимной зависимости (сервисы легко разделяются)

Поэтому было создано отдельное приложение, которое в будущем будет вызываться через urlfetch и выдавать данные по конкретному IP.

Ограничение в 1мб было преодалено созданием RequestHandler'а для получения части файла и загрузки этой части объектов в сторедж.

На стороне же клиента есть маленький скрипт, который методом POST отправляет данные.

И вот тут...



… начинаются танцы «в стиле жесткого диско». Как оказалось, после 40000 вставленных объектов, сожрался 1 час процессорного времени. Причем, подумав что отдельные put для каждого объекта – дело расточительное, решил попробовать db.put() (т.н. batch put), который вставляет объекты пачками.

Как выяснилось, db.put не только не уменьшил CPU time для каждого запроса (напомню, локальный скрипт передает 200 строк из файла ip блоков за один запрос и так до конца файла), но и увеличил его примерно на 10%. Согласитесь, что-то здесь не так. Пока не понял в чем проблема, но на мой взгляд db.put просто вызывает put у всех объектов в списке (да, он ещё вставляет объекты по возможности в одной транзакции, но это не наш случай).

При простом пересчете получается что-то около 10 долл на загрузку всей базы (без локаций)

Итого, при разработке под GAE:


  • Думайте как будете загружать большие объемы данных. Лучше придумать как собирать их по ходу жизни приложения.
  • Используйте ресурс в 10 приложений, создавайте веб-сервисы для своих сервисов и будьте самым сервисным из сервисных. Это позволит так или иначе уменьшить затраты на ресурсы и уйти от «жестких» лимитов, если требуется. Это основной способ «дотягивания» возможностей GAE до ваших нужд.
  • На данный момент db.put() не имеет преимуществ в производительности перед Model.put()


Жду вас в своем ЖЖ.
Tags:
Hubs:
+2
Comments 24
Comments Comments 24

Articles