Pull to refresh

Google App Engine – масштабируемые приложения

Reading time3 min
Views3.3K
Google App Engine позволяет легко создавать приложения, надежно работающие даже при большой нагрузке и с большими объемами данных. Но ещё проще создать программного монстра, который будет работать очень медленно или вовсе не работать, постоянно возвращая ошибку HTTP 500.

Как писать быстрые и хорошо масштабируемые приложения – об этом пойдет речь в этой статье.

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


Одна секунда


Google App Engine позволяет каждому приложению обслуживать до 500 запросов в секунду, но только в том случае, если выполнение каждого запроса в среднем занимает не более одной секунды. В противном случае приложение, как неэффективное, будет ограничено, и уже при сравнительно небольшой нагрузке часть запросов начнет завершаться ошибкой HTTP 500.

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

Если совсем обойтись без «длинных» запросов не представляется возможным, то необходимо минимизировать частоту их появления – «размазать» среди быстрых запросов – после чего экспериментально убедиться, что приложение не попало под ограничения. При этом нужно помнить, что ограничения накладываются и снимаются системой постепенно.

Тридцать секунд


Хранилище данных в App Engine позволяет приложениям эффективно работать с огромным объемом данных благодаря своей распределенной архитектуре, но из-за неё же в среднем 1 из 3000 операций с хранилищем заканчивается тайм-аутом. Такие операции автоматически повторяются, но если после нескольких повторов операцию завершить так и не удалось, то генерируется DatastoreTimeoutException, при отсутствии обработчика которого приложение завершится ошибкой HTTP 500.

Для быстрых запросов, обработка которых занимает меньше секунды, автоматические повторы уменьшают частоту появления DatastoreTimeoutException. Во время же выполнения «длинных» запросов, которые интенсивно работают с хранилищем, вероятность генерации исключения значительно выше. Часто такие запросы вообще завершаются DeadlineExceededException, потому что при многократном повторении неудачного «тяжелого» обращения к хранилищу приложение может исчерпать 30-секундный тайм-аут, отведенный на обработку запроса.

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

Десять раз в секунду


Все объекты в хранилище относятся к какой-нибудь группе объектов (entity group). К каждой группе принадлежат объекты, между которыми определено отношение зависимости. Объект, независящий от других объектов, принадлежит к группе, состоящей из него самого. Группы объектов помогают App Engine хранить связанные объекты вместе в распределенном хранилище.

Распределенная архитектура хранилища позволяет распараллеливать операции с объектами, но только в том случае, если они принадлежат к разным группам. Для объектов, являющихся частью одной группы, поддерживается не более 10 операций записи в секунду.

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

Проектируя приложение, нужно ясно представлять как объекты будут объединены в группы, и как часто будет модифицироваться каждая из них, в том числе с учетом роста числа пользователей приложения. Чтобы приложение хорошо масштабировалось необходимо придерживаться небольших групп объектов, а для часто обновляемых данных использовать технику шардинга (sharding).

Резюме


Google App Engine позволяет легко создавать приложения, надежно работающие даже при большой нагрузке и с большими объемами данных, но только в том случае если запросы к приложению выполняются быстро, обмен данными с хранилищем осуществляется небольшими порциями, а сами данные организованы в небольшие группы объектов.



Статья написана Александром, который пока ещё не присутствует на Хабре.
Александр на Хабре — windicted
Tags:
Hubs:
Total votes 84: ↑69 and ↓15+54
Comments26

Articles