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

Случилось как-то раз Емеле узнать откуда родом посетители его хомяка (утрирую), для чего Емеля обратился в 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()


Жду вас в своем ЖЖ.