Хранение данных в Google App Engine
За основу данной статьи взята запись в блоге Ника Джонсона (Nick Johnson). В дополнение к ней приведено немного цифр, актуальных на данный момент и добавлены некоторые заметки.
App Engine предоставляет множество способов хранения информации. Некоторые (например, хранилище данных) хорошо известны, но другие почти нет, и у всех них характеристики различаются. В этой статье будут перечислены различные возможности и описаны преимущества и недостатки каждой из них, так что Вы сможете принимать решения, имея больше информации о возможностях хранения данных.
Хранилище данных (datastore)
Самое известное, используемое и гибкое хранилище данных. Datastore — это нереляционная база данных App Engine, она предоставляет надёжное долговременное хранилище, а также обеспечивает максимальную гибкость в хранении, получении и обработке данных.
- Достоинства:
- Надёжно — данные сохраняются всерьёз и надолго.
- Чтение и запись — приложения могут как считывать, так и записывать данные в datastore. Также, datastore обеспечивает механизм транзакций для обеспечения целостности.
- Согласованно — вид хранилища одинаков для всех инстансов приложения.
- Гибко — запросы (queries) и индексирование обеспечивают много способов запроса и получения данных
- Недостатки:
- Скорость — так как datastore хранит данные на диске и обеспечивает гарантированную надёжность, процесс записи требует ожидания подтверждения того, что данные сохранены, а процесс чтения вынужден брать данные с диска.
- Как и где использовать:
Специально обученное описание datastore находится здесь.
Использовать datastore следует везде, где необходимо надёжно сохранить данные, в будущем используемые приложением.
- Где лучше не использовать:
Зачастую разработчики пишут в базу отладочную и техническую информацию, необходимую только им. Для таких случаев гораздо лучше подходят встроенные логи App Engine, речь о них пойдёт ниже.
Memcache
Memcache известен как механизм «вторичного» хранения данных. API memcache предоставляет приложениям возможность оптимистично кэшировать данные во избежание дорогостоящих операций. Memcache часто используется в качестве уровня кэширования для других API, таких как datastore, или для кэширования результатов любых вычислений.
- Достоинства:
- Быстро — время доступа к memcache обычно составляет несколько миллисекунд
- Согласованно — вид хранилища одинаков для всех инстансов приложения. Кроме того, memcache обеспечивает атомные операции, так что приложения могут гарантировать целостность хранимых в нём данных.
- Недостатки:
- Ненадёжно — данные могут быть удалены из memcache в любой момент.
- Не всегда доступно — в периоды обслуживания App Engine memcache недоступен.
- Как и где использовать:
В качестве кэша datastore, urlfetch или результатов вычислений.
- Где лучше не использовать:
Для хранения важных данных, не стоит забывать, что из memcache они могут пропасть в любой момент.
Память инстанса
Инстансы приложения тоже могут кэшировать данные с помощью использования глобальных переменных или членов класса. Этот способ обеспечивает наивысшую скорость, но обладает некоторыми недостатками.
- Достоинства:
- Быстро — буквально, настолько быстро, насколько это возможно, так как данные хранятся в том же процессе, что их запрашивает.
- Удобно — нет необходимости в API, данные просто хранятся в глобальных переменных или в членах класса.
- Гибко — данные могут храниться в любом формате, в котором Ваша программа может их обрабатывать. Нет необходимости в их сериализации/десериализации.
- Недостатки:
- Ненадёжно — инстансы могут запуститься или остановиться в любой момент, поэтому приложениям следует использовать память инстанса только в качестве кэша.
- Несогласованно — у каждого инстанса своё окружение среды и, следовательно, свои глобальные переменные. Изменения в одном инстансе не отразятся в других инстансах.
- Ограниченная вместимость — у инстансов есть ограничение потребляемой памяти, после превышения которого они уничтожаются. Предельный объём для данных в памяти инстанса около 50Мб — при использовании большего объёма инстансы будут уничтожаться очень часто.
- Как и где использовать:
Для кэширования часто используемых и редко изменяемых данных — информации о сессиях, настроек приложения, гостевых страниц и т.д. Особенно удобно использование памяти инстанса в переменных dict — можно создать своеобразные хранилища «ключ-данные» для различных видов данных.
- Где лучше не использовать:
Для кэширования часто изменяемых данных или данных, с которыми взаимодействует пользователь. Разные запросы одного пользователя могут обрабатываться разными инстансами и кэширование в таком случае внесёт существенную путаницу.
Blobstore
Хранилище BLOB-ов позволяет легко и эффективно хранить и отдавать большие объёмы данных, загруженных пользователем.
- Достоинства:
- Поддерживает большие файлы — до 2-х Гб на blob.
- Избавляет от необходимости написания обработчиков.
- Предоставляет механизм для высокопроизводительного обслуживания blob-ов, особенно изображений.
- Приложения могут читать содержимое blob-ов как если бы это были локальные файлы.
- Недостатки:
-
Только чтение — приложение не может создавать blob-ы или изменять уже загруженные.30 марта 2011 в App Engine появился Files API — теперь данные в blobstore можно изменять. - Для использования blobstore необходимо включить биллинг.
-
- Как и где использовать:
Для хранения пользовательских изображений, файлов и прочих больших объектов.
- Где лучше не использовать:
Для небольших файлов, с которыми планируется взаимодействие приложения лучше подходит BlobProperty в datastore.
Локальные файлы
Приложение может читать любые файлы, загруженные с приложением и не отмеченные как статический контент, используя стандартные операции файловой системы. Так добавляются данные только для чтения, которые могут понадобиться приложению.
- Достоинства:
- Быстро — чтение локальных файлов задействует только стандартные дисковые операции на той машине, на которой запущен инстанс приложения, так что скорость почти такая же, как у memcache.
- Надёжно — если приложение работает, то локальные файлы всегда доступны.
- Гибко — можно использовать любой формат или механизм доступа к локальным файлам.
- Недостатки:
- Только чтение — приложения не могут модифицировать файлы.
- Ограниченный размер — ограничения составляют 10Мб на файл и 150Мб на приложение.
- Как и где использовать:
Хранение настроек приложения, шаблонов и т.д.
- Где лучше не использовать:
Противопоказаний не замечено
Нагрузка очереди задач (Task queue payloads)
Это не хранилище в его традиционном понимании, к задачам из taskqueue могут прикрепляться данные, которые могут устранить необходимость использования других систем хранения.
- Достоинства:
- Быстро — данные отправляются задаче тогда, когда она запускается, так что для получения данных не требуется дополнительных вызовов API.
- При правильном использовании позволяет избежать необходимости хранения данных где-то ещё.
- Недостатки:
- Только для одной задачи — нагрузка полезна только как хранилище для данных, отправляемых задаче taskqueue
- Ограниченный размер — размер задач, включая нагрузку, не должен превышать 10Кб
- Как и где использовать:
Фоновая обработка данных, отправка почты, обновление кэша — любые работы, перенесение которых в фоновое исполнение позволит ускорить оптравку ответа пользователю и не влияет на полученный пользователем ответ сервера.
- Где лучше не использовать:
Обработка более 10Кб данных потребует использования других способов хранения. Также следует не забывать, что в некоторых случаях задачи из taskqueue могут выполняться с существенной задержкой.
Электронная почта
В App Engine электронную почту можно использовать не только для общения с пользователями, но и в технических целях. В данном случае способ передачи данных похож на использование taskqueue payload, однако использование электронной почты предоставляет больше возможностей, например, передача данных другому приложению App Engine.
- Достоинства:
- Гибко — можно отправлять большие объёмы с помощью отправки «обычной» почты или отправлять «админскую» почту, не затрагивая почтовые квоты.
- Удобно — письмо с данными приходит как POST-запрос, для удобства обработки которого имеется стандарнтый InboundMailHandler.
- Возможность обмена данными между приложениями.
- Недостатки:
- Спам — на адрес приложения могут приходить незапланированные письма, необходима дополнительная проверка входящих данных.
- При отправке необходимо пользоваться разными методами в зависимости от объёма данных — администраторам можно отправлять письма не больше, чем 16Кб, а отправка обычных писем стоит относительно дорого.
- Для полноценной работы с «админской» почтой желательно включать биллинг. Приложение с включенным биллингом может отправить администраторам 3 492 979 писем в сутки, в то время, как с отключенным всего 5 000.
- Нетривиальный процесс подключения адреса приложения в качестве администраторского — необходим временный обработчик для заведения аккаунта Google на данный адрес и включения его в список администраторов.
- Как и где использовать:
Передача небольших объёмов данных (до 16Кб) между приложениями.
- Где лучше не использовать:
Частая передача больших объёмов данных быстро израсходует почтовую квоту — для этих целей больше подойдёт URLFetch.
URLFetch
API получения данных по URL позволяет получать информацию от других хостов с помощью HTTP и HTTPS-запросов.
- Достоинства:
- Возможность получить данные с других приложений/серверов.
- Асинхронность — при получении данных асинхронно во время ожидания можно выполнять другие вычисления.
- Размер — приложение может получить до 32Мб за один запрос, однако отправить через этот API можно не более 1Мб.
- Недостатки:
- Скорость зависит от скорости другого хоста.
- Трафик — для службы URLFetch и пользователей единая квота трафика. Слишком активное использование URLFetch может привести к отказам в обслуживании пользователей.
- Как и где использовать:
Фоновая загрузка и обработка данных, например RSS. Взаимодействие со сторонними приложениями, например с reCaptcha.
- Где лучше не использовать:
Получение данных для пользователя, когда это возможно осуществить более быстрыми методами.
Логи приложения
Обычно этот метод незаслуженно забыт и для сбора информации о работе приложения используется datastore. Однако, если Вы не хотите уменьшать быстродействие приложения во время сбора технической и отладочной информации, то этот метод подойдёт гораздо лучше.
- Достоинства:
- Быстро — запись в лог занимает несколько миллисекунд.
- Удобное разделение сообщений по приоритету.
- Недостатки:
- Только запись — приложение не имеет доступа к логам.
- Только текстовые данные, кириллица в логах может вызвать ошибки.
- Необходимость парсить — наличие функции request_logs в инструментах разработчика позволяет лишь получить логи в виде текста, для его обработки потребуется отдельный парсер.
- Как и где использовать:
Для сбора информации о работе приложения, измерений времени выполнения запросов, оповещения о медленной работе функций или о нештатных ситуациях.
- Где лучше не использовать:
В некоторых случаях статистику работы приложения целесообразнее хранить в datastore. В таких случаях данные лучше передавать в задачу taskqueue и записывать её в datastore в фоновом режиме.
Заключение
App Engine даёт гораздо больше способов хранения данных, чем кажется на первый взгляд. В каждом из них свои компромиссы, так что вероятно, что Вашему приложению подойдёт один (или больше) из них. Часто оптимально решение включает в себя комбинацию методов, например, datastore и memcache, или локальные файлы и память инстанса.