Pull to refresh

Оптимизация под новый прайс

Reading time 7 min
Views 1.2K
Original author: Alon Levi
image
App Engine полным ходом идёт к светлому будущему и новой методике расчёта за ресурсы. Паника и хаос вселились в ряды разработчиков под AE — слишком многое держится в строжайшем секрете (или в компании тоже толком не знают что как будет). Но сегодня мы не будем обсуждать, будет ли blobstore включен в бесплатные квоты, или за один лишь доступ к нему придётся платить. Не обсудим куда податься, если новые цены совсем не по карману и не будем говорить о $50 «халявы», которыму гугъл пытается смягчить переход на новые рельсы (тем более, что эту радостную весть разослали всем администраторам приложений).

Сегодня речь будет идти об оптимизации приложений. Вы же уже оптимизировали своё приложение на минимальное потребление процессорного времени и памяти? Забудьте об этом, теперь это вторично и Ваши кровные будут сниматься по другим меркам.

Вступление.


В качестве части процесса перехода на новые цены, мы обновили набор ресурсов, включенный в отчёт использования приложения. Мы отказываемся от часов процессорного времени и движемся к системе, которая будет учитывать количество часов работы инстансов (Frontend и Backend), количество вызовов API, объём хранимых данных и трафик. Более подробная информация в нашем FAQ.

Перед запуском новой модели ценообразования мы выпустили сравнительные счета, чтоб Вы могли посмотреть, как она повлияет на Ваши расходы. Вы можете начать оптимизировать Ваше приложение до того, как изменения цен вступят в силу и посмотреть как оптимизации отразятся на Вашем счёте.

В этой статье мы покажем, как толковать новый отчёт использования и покажем некоторые стратегии, которые можно использовать для управления ресурсами, и как они могут повлиять на производительность Вашего приложения.

Изучаем старые и новые отчёты.


Ежедневные отчёты использования находятся в панели управления на странице Billing History, расположенной по адресу _https://appengine.google.com/billing/history?&app_id=$APP_ID. Клик по значку [+] возле одного из отчётов развернёт подробности одного дня, где Вы сможете увидеть новые и старые ресурсы. Предпросмотр отчёта использования для Вашего приложения выглядит примерно так:
image
Мы пройдёмся по списку параметров в счёте и объясним что они обозначают, прделожим некоторые стратегии управления ресурсами и объясним, как они повлияют на производительность приложения.

Управление использованием инстансов.


Первые две строки нового счёта касаются использования инстансов приложения. Вы можете почитать об инстансах в нашей документации. Количество используемых приложением инстансов Вы можете посмотреть в панели управления по адресу _https://appengine.google.com/instances?&app_id=$APP_ID или выбрав график Instances в выпадающем списке по адресу _https://appengine.google.com/dashboard?&app_id=$APP_ID.

Планировщик App Engine.


App Engine использует алгоритм планирования для определения того, как много инстансов необходимо приложению для обслуживания его трафика. При каждом запросе, полученном Вашим приложением, мы принимаем решение, обслуживать ли его доступному инстансу (тому, что простаивает или принимает параллельные хапросы), отправить ли запрос в очередь ожидания, или запустить новый инстанс для этого запроса. Мы принимаем решение на основе доступных инстансов, скорости, с которой приложение отвечает на запросы (его latency) и времени, которое занимают запуск и инициализация нового инстанса до начала обслуживания запросов. В большинстве случаев, когда мы считаем, что можем обслужить запрос быстрее, запустив новый инстанс, мы запускаем новый инстанс.

Конечно, трафик приложения непостоянен, так что планировщик продолжает отслеживать количество простаивающих инстансов Вашего приложения. Эти инстансы могут пригодиться для обслуживания скачков трафика без заметной пользователю задержки. Если планировщик определяет, что у приложения слишком много простаивающих инстансов, то он отзывает ресурсы, останавливая один из инстансов.

Стратегии уменьшения количества используемых инстансов.


Уменьшение задержек (latency).

Задержки Вашего приложения оказывают большое влияние на количество инстансов, необходимых для обслуживания приложения. Поэтому уменьшение задержки может сильно сказаться на количестве необходимых инстансов. Вот список действий для уменьшения задержки:
  • Больше кэшируйте часто используемые общие данные. Говоря другими словами: используйте Memcache. Если Вы также установить заголовки cache-control для приложения, то сможете сильно увеличить эффективность кэширования серверами и браузерами. Даже кэширование на несколько секунд может сильно поднять эффективность приложения. Приложениям на python'e следует использовать ещё и кэширование в среде выполнения.
  • Используйте Memcache более эффективно. Используйте пакетные вызовы вместо ряда одиночных.
  • Используйте задачи (Tasks) для действий, не связанных с запросами. Если Ваше приложение выполняет действия, которые можно выполнить за пределами обслуживающего пользователя запроса — отправьте его в задачи. Отправка этих действий в очередь задач (Task Queue) вместо ожидания выполнения до завершения запроса позволит существенно снизить заметные пользователю задержки. Очередь задач может обеспечить гораздо больший контроль над скоростью выполнения и помогает распределить нагрузку более равномерно.
  • Используйте хранилище данных более эффективно. Мы углубимся в детали ниже.
  • Отправляйте запросы URL Fetch параллельно.
    • Используйте асинсхронные вызовы API (Java, Python)
    • Объединяйте вызовы URL Fetch в пакеты (которые Вы можете обрабатывать по одному во время запроса пользователя) и обрабатывайте их в оффлайн-задаче параллельно асинхронному URL Fetch.
  • Записывайте HTTP-сессии на Java асинхронно. Сессии HTTP позволяют настроить приложение на на асинхронную запись данных сессии в datastore добавлением <async-session-persistence enabled="true"/> в файл appengine-web.xml. Данные сессии всегда синхронно записываются в memcache, и если запрос пытается получить данные, которых в memcache нет, то запрос отправляется к datastore, в котором может ещё и не быть последнего обновления. Это означает, что есть небольшой риск, что приложение получит просроченные данные сессии, но для большинства приложений выигрыш в скорости сильно перевешивает этот риск.

Подстройте планировщик вручную.

На странице настроек приложения (Application Settings) в панели управления есть два слайдера, которые помогут Вам установить некоторые переменные, используемые планировщиком для управления инстансами приложения. Вот краткое объяснение того, как их использовать для поиска компромисса между производительностью и использованием ресурсов:
  • Уменьшите максимальное количество простаивающих инстансов. Настройка Max Idle Instances позволяет контролировать максимальное количество простаивающих инстансов приложения. Установка этого ограничения говорит App Engine останавливать любые простаивающие инстансы сверх этого ограничения, чтобы они не потребляли дополнительные квоты или несли дополнительные расходы. Однако, меньшее количество простаивающих инстансов также означает, что планировщику App Engine придётся запустить новые инстансы во время скачка трафика, что может увеличить заметные пользователям задержки.
  • Увеличьте минимальную задержку ожидания. Увеличение минимальной задержки ожидания (Min Pending Latency) говорит планировщику App Engine не запускать новый инстанс до тех пор, пока запрос не находится в очереди более указанного времени. Если все инстансы заняты, то обслуживающему пользователя запросу может понадобиться ждать в очереди достижения этого порога. Установка большого значения для этого параметра потребует запуска меньшего количества инстансов, но может вылиться в большие заметные пользователю задержки во время повышенной нагрузки.

Включите параллельные запросы (Concurrent Requests) на Java.

В релизе 1.4.3 мы представили возможность для инстансов Вашего приложения обслуживать несколько одновременных запросов на Java. Включение этого параметра уменьшит количество необходимых инстансов, но для корректной работы с ним Ваше приложение должно быть потокобезопасным. Прочитать больше о параллельных запросах Вы можете в документации по Java.

Примечание: многопоточность для Python будет недоступна до запуска Python 2.7, имеющегося в плане работ. В Python 2.7 многопоточные инстансы могут обрабатывать больше запросов и не должны потреблять квоты часов работы инстансов при простое во время ожидания ответов блокирующих API. Так как Python сейчас не поддерживает возможность одновременного обслуживания более, чем одного запроса для одного инстанса, и чтобы позволить всем разработчикам приспособиться к одновременным запросам, мы предоставим скидку 50% на часы работы frontend-инстансов до 20 ноября 2011. Python 2.7 сейчас в стадии закрытого тестирования.

Управление хранилищем приложения.


App Engine вычисляет стоимость хранения на основе размера объектов в хранилище данных, размера индексов, необходимых для обслуживания данных, и количества данных в blobstore.
Вот некоторые действия, которые Вы можете выполнить, чтобы проверить, не находится ли в индексе больше данных, чем нужно:
  • Используйте функцию «Get Indexes» (Java, Python), чтобы проверить, какие индексы установлены для Вашего приложения. Удаление любых индексов, не являющихся необходимыми для приложения позволит сэкономить на хранении данных и уменьшит стоимость записи объекта. Также, Вы можете посмотреть работающие индексы приложения в панели управления по адресу _https://appengine.google.com/datastore/indexes?&app_id=$APP_ID.
  • При проектировании моделей данных проверьте, можете ли Вы написать запросы так, чтобы уменьшить общее количество индексов. Прочтите нашу документацию по запросам и индексам, чтобы получить больше информации о том, как App Engine создаёт индексы.


Управление использованием datastore.


В новой модели мы будем учитывать количество операций, выполненных в datastore (вместо используемых сейчас ресурсов CPU). Несколько стратегий, которые могут привести к уменьшению потребления ресурсов datastore, а также к меньшим задержкам запросов к datastore:
  • Перенастройте моделирование данных так, чтобы заменить запросы более эффективным и дешёвым получением по ключу.
  • Используйте запросы только ключей вместо запросов всех объектов, когда такое возможно.
  • Для уменьшения задержки заменяйте несколько одиночных запросов get() на один пакетный get().
  • Для нумерации страниц используйте указатели datastore вместо смещения.
  • Распараллельте несколько запросов к datastore с помощью асинхронного API datastore (Java, Python).


Управление трафиком.


Главный способ уменьшить исходящий трафик, это всегда, когда возможно ставить соответствующий заголовок Cache-Control в ответах и устанавливать разумный срок действия для статических файлов (Java, Python). Использование заголовка Cache-Control: public позволит прокси-серверам и браузерам пользователей кэшировать ответы в течение назначенного времени.

Входящий трафик контролировать сложнее, так как это количество данных, отправляемых пользователями приложению. Однако, это хорошая возможность упомянуть сервис защиты от DoS (Java, Python), который позволит Вам блокировать трафик с нежелательных IP.

Управление другими ресурсами.


Последние значения в отчёте — использование API Email, XMPP, и Channel. Для этих API лучше всего убедиться, что Вы используете их эффективно. Один из лучших способов проверки использования API — использовать Appstats (Python, Java) чтобы убедиться, что приложение не делает лишних вызовов. Также, всегда хорошая идея — убедиться, что Вы проверяете уровень ошибок и смотрите за любыми возможными неверными вызовами. В некоторых случаях возможно отловить такие вызовы заранее.
Tags:
Hubs:
+19
Comments 29
Comments Comments 29

Articles