1. Обзор
Эта серия учебных пособий (практических руководств для самостоятельного обучения) призвана помочь разработчикам Google App Engine (стандартной версии) модернизировать свои приложения, проведя их через серию миграций. Большинство таких миграций связано с отказом от исходных комплексных служб среды выполнения, поскольку среды выполнения следующего поколения являются более гибкими и предоставляют пользователям большее разнообразие вариантов обслуживания. Другой способ модернизации приложения включает обновление до более нового продукта, и это тема данной лаборатории.
Пользователи App Engine, получающие доступ к Datastore с помощью клиентских библиотек Cloud NDB или Cloud Datastore, готовы к использованию и не нуждаются в дальнейшей миграции. Однако Cloud Firestore представляет собой новейшее, масштабируемое, высокодоступное хранилище данных NoSQL с функциями базы данных реального времени Firebase .
Вы попали по адресу, если вы разработчик, который чувствует необходимость использовать Firestore, чтобы воспользоваться его функциями или, по крайней мере, у вас достаточный интерес, чтобы изучить, что влечет за собой миграция. Из этого руководства вы узнаете, как перенести приложение App Engine с помощью Cloud Datastore в Cloud Firestore.
Вы узнаете, как
- Признайте различия между Datastore и Firestore.
- Миграция с Cloud Datastore на Cloud Firestore
Что вам понадобится
- Проект Google Cloud Platform с:
- Базовые навыки Python
- Знание основных команд Linux.
- Базовые знания разработки и развертывания приложений App Engine.
- Перед началом этого модуля (Модуль 6) рекомендуется выполнить лабораторную работу по Модулю 3 , включая его перенос на Python 3.
- Рабочее приложение Cloud Datastore Python 3 App Engine Модуля 3 .
Опрос
Как вы будете использовать эту кодовую лабораторию?
2. Предыстория
В 2013 году хранилище данных App Engine стало отдельным продуктом , Google Cloud Datastore, и теперь доступно разработчикам за пределами App Engine. В следующем году Firebase была приобретена Google. В то время он был известен своей базой данных, работающей в режиме реального времени.
В течение следующих нескольких лет команды Firebase и Cloud Datastore работали над интеграцией некоторых функций Firebase в Datastore. В результате в 2017 году было выпущено следующее поколение Cloud Datastore. Чтобы отразить унаследование некоторых функций Firebase, он был переименован в Cloud Firestore .
Cloud Firestore стал механизмом хранения NoSQL по умолчанию для проектов Google Cloud. Новые приложения могут использовать Cloud Firestore изначально, в то время как существующие базы данных Datastore были конвертированы в Firestore и теперь работают как «Firestore в режиме Datastore», чтобы сохранить совместимость с операциями Datastore. В результате приложения могут работать с Cloud Firestore только в одном из этих режимов, и после настройки его нельзя изменить.
В настоящее время, когда пользователи создают новые проекты и выбирают решение NoSQL, им предлагается выбрать либо Firestore в режиме хранилища данных, либо Firestore в собственном режиме. Как только пользователи добавляют объекты хранилища данных, они не могут перейти на Firestore, и аналогичным образом, если выбран собственный режим Firestore, они больше не могут переключиться обратно на хранилище данных (или, скорее, на Firestore в режиме хранилища данных). Для получения более подробной информации прочтите в документации выбор между Cloud Firestore в режиме хранилища данных или собственным режимом Firestore . Чтобы перенести приложение в Firestore, необходимо создать новый проект, экспортировать Datastore, а затем импортировать его в Firestore. Цель этого руководства — дать разработчикам представление о различиях между использованием Cloud Datastore и Cloud Firestore.
Мы не ожидаем, что пользователи будут выполнять эту миграцию , поэтому она является необязательной. Хотя изначальное использование Cloud Firestore имеет очевидные преимущества, такие как аутентификация клиента, интеграция правил Firebase и, конечно же, база данных реального времени Firebase, этапы миграции «неудобны»:
- Вы должны использовать проект, отличный от проекта вашего текущего приложения.
- Проект, в который приложение добавило объекты Datastore, нельзя переключить на Firestore в собственном режиме.
- Аналогично, проект, в котором Firestore выбран в собственном режиме, не может вернуться обратно в Firestore в режиме хранилища данных.
- Не существует инструмента миграции, который мог бы передавать данные из одного проекта в другой.
- Некоторые важные функции хранилища данных, включая пространства имен и более высокую пропускную способность записи (> 10 КБ/с), недоступны в Firestore.
- Инструменты экспорта и импорта представляют собой «примитивные» сценарии и сценарии «все или ничего».
- Если в вашем приложении много объектов Datastore, экспорт и импорт в Firestore может занять много часов.
- В течение этого времени ваше приложение/служба не сможет записывать/обновлять данные.
- Действия по миграции засчитываются в нормальное использование; вы можете распределить его (если возможно, по ежедневным квотам), чтобы минимизировать затраты.
- Поскольку ваша новая служба работает в другом проекте, вам понадобится окно для распространения обновлений DNS.
- Datastore и Firestore имеют схожие, но разные модели данных, поэтому миграция требует обновления того, как работает приложение/сервис.
- Запросы предков из хранилища данных теперь являются запросами коллекции Firestore (по умолчанию).
- Запросы широкого типа из Datastore — это групповые запросы Firestore Collection.
- Индексы и обработка разные и т.д.
Тем не менее, если у вас есть довольно простое приложение, которое можно рассмотреть для миграции, вы готовитесь к моделированию такой миграции или просто хотите узнать о Datastore и Firestore, продолжайте!
Для пользователей Python 2: эта дополнительная кодовая лаборатория миграции представлена только в Python 3, однако, поскольку Cloud Firestore также поддерживает 2.x, пользователи могут интерполировать различия в использовании. Одним из примеров является то, что записи Firestore используют строки Unicode (вместо байтовых строк), поэтому для строковых литералов Python 2 требуется ведущий индикатор u''
, что означает, что функция store_visit()
версии 2.x будет выглядеть следующим образом:
def store_visit(remote_addr, user_agent):
doc_ref = fs_client.collection(u'Visit')
doc_ref.add({
u'timestamp': datetime.now(),
u'visitor': u'{}: {}'.format(remote_addr, user_agent),
})
В остальном клиентская библиотека должна работать аналогично. Единственная другая проблема, которую следует принять во внимание, заключается в том, что библиотека Cloud Firestore 2.x «заморожена» на этапе разработки, поэтому все больше и новые функции будут доступны только в клиентской библиотеке Firestore 3.x.
Ниже приведены основные шаги этого руководства.
- Настройка/Предварительная работа
- Добавить библиотеку Cloud Firestore
- Обновить файлы приложения
3. Настройка/Предварительная работа
Прежде чем мы приступим к основной части руководства, давайте настроим наш проект, получим код, а затем развернем базовое приложение, чтобы мы знали, что начали с рабочего кода.
1. Проект установки
Мы рекомендуем повторно использовать тот же проект, который вы использовали для выполнения лабораторной работы по Модулю 3 . Альтернативно вы можете создать новый проект или повторно использовать другой существующий проект. Убедитесь, что у проекта есть активный платежный аккаунт и включен App Engine (приложение).
2. Получите базовый образец приложения.
Одним из обязательных условий для этой лаборатории кода является наличие рабочего примера приложения Модуля 3. Если у вас его нет, пройдите руководство по Модулю 3 (ссылка выше), прежде чем двигаться дальше. В противном случае, если вы уже знакомы с его содержимым, вы можете просто начать с кода Модуля 3 ниже.
Независимо от того, используете ли вы свой или наш, мы НАЧНЕМ с кода Модуля 3. Эта лаборатория кода Модуля 6 проведет вас через каждый шаг, и по завершении она должна напоминать код в точке ФИНИШ. (Это руководство доступно только для Python 3.)
- НАЧАЛО: репозиторий модуля 3
- ЗАВЕРШЕНИЕ: репозиторий модуля 6.
- Весь репозиторий (клонировать или скачать ZIP)
Каталог файлов Модуля 3 (ваших или наших) должен выглядеть следующим образом:
$ ls
README.md main.py templates
app.yaml requirements.txt
3. (Повторно) разверните приложение Модуля 3.
Оставшиеся подготовительные шаги, которые необходимо выполнить сейчас:
- Повторно ознакомьтесь с инструментом командной строки
gcloud
(если необходимо). - (Повторно) разверните код Модуля 3 в App Engine (если необходимо).
После того как вы успешно выполнили эти шаги и подтвердили его работоспособность, мы продолжим работу с этим руководством, начиная с файлов конфигурации.
Требования Python 2
- Убедитесь, что
app.yaml
(по-прежнему) ссылается на сторонние пакеты:grpcio
иsetuptools
. - Убедитесь, что
appengine_config.py
по-прежнему используетpkg_resources
иgoogle.appengine.ext.vendor
, чтобы указать приложению сторонние ресурсы. - В следующем разделе, обновляющем
requirements.txt
, вы должны использоватьgoogle-cloud-firestore==1.9.0
поскольку это последняя версия клиентской библиотеки Python Firestore, совместимая с версией 2.x.- Если в
requirements.txt
есть запись дляgoogle-cloud-core
, оставьте ее как есть. - Удалите
lib
и переустановите ее с помощьюpip install -t lib -r requirements.txt
.
- Если в
4. Обновите файлы конфигурации (добавьте библиотеку Cloud Firestore).
Помимо установки, следующие необходимые шаги — обновить конфигурацию, а затем файлы приложения. В первом случае единственным изменением конфигурации является незначительная замена пакета в файле requirements.txt
, поэтому давайте сделаем это сейчас.
Замените строку google-cloud-datastore
на google-cloud-firestore
в requirements.txt
, чтобы она выглядела следующим образом:
Flask==1.1.2
google-cloud-firestore==2.0.2
Мы рекомендуем использовать последние версии каждой библиотеки; номера версий, указанные выше, являются последними на момент написания этой статьи. Код в папке репозитория FINISH обновляется чаще и может иметь более новую версию.
Других изменений конфигурации нет, поэтому app.yaml
и templates/index.html
остаются без изменений.
5. Обновите файлы приложения.
Существует только один файл приложения — main.py
, поэтому все изменения в этом разделе затрагивают только этот файл.
1. Импорт
Переключение импорта пакетов — это незначительное изменение с datastore
на firestore
:
- ДО:
from google.cloud import datastore
- ПОСЛЕ:
from google.cloud import firestore
2. Доступ к пожарному магазину
После инициализации Flask создайте клиент Firestore. Внесите аналогичные изменения, как указано выше, но для инициализации клиента:
- ДО:
app = Flask(__name__)
ds_client = datastore.Client()
- ПОСЛЕ:
app = Flask(__name__)
fs_client = firestore.Client()
Выполняя миграцию из Cloud NDB в Cloud Datastore, вы уже проделали тяжелую работу по переходу в Cloud Firestore. С помощью Datastore вы создаете записи данных в виде сущностей, состоящих из общих свойств, и группируете их по ключам . Записи данных в Firestore представляют собой документы, состоящие из пар ключ-значение и сгруппированные в коллекции . Миграция с Datastore требует, чтобы вы подумали об этих различиях, поскольку они проявятся, когда вы создаете записи данных, а также выполняете к ним запросы. Результаты могут различаться в зависимости от того, насколько сложен код вашего хранилища данных.
Для хранилища данных вы делаете запросы на основе типа сущности, а также критериев фильтрации и сортировки . Для Firestore запрос данных аналогичен. Давайте рассмотрим быстрый пример, предполагая, что эти значения запроса, клиенты ( ds_client
или fs_client
соответственно) и импорт:
from datetime import datetime
from firestore.Query import DESCENDING
OCT1 = datetime(2020, 10, 1)
LIMIT = 10
Для хранилища данных давайте запросим десять последних объектов Visit
, датированных 1 октября 2020 г., в порядке убывания:
query = ds_client.query(kind='Visit')
query.add_filter('timestamp', '>=', datetime(2020, 10, 1))
query.order = ['-timestamp']
return query.fetch(limit=LIMIT)
То же самое делаем для Firestore из коллекции Visit
:
query = fs_client.collection('Visit')
query.where('timestamp', '>=', datetime(2020, 10, 1))
query.order_by('timestamp', direction=DESCENDING)
return query.limit(LIMIT).stream()
Пример запроса приложения проще (без предложения WHERE). В качестве обзора приведем код Cloud Datastore:
- ДО:
def store_visit(remote_addr, user_agent):
entity = datastore.Entity(key=ds_client.key('Visit'))
entity.update({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
ds_client.put(entity)
def fetch_visits(limit):
query = ds_client.query(kind='Visit')
query.order = ['-timestamp']
return query.fetch(limit=limit)
При переходе на Firestore вы обнаружите создание новых документов, похожих на сущности, и запросы, как показано ранее.
- ПОСЛЕ:
def store_visit(remote_addr, user_agent):
doc_ref = fs_client.collection('Visit')
doc_ref.add({
'timestamp': datetime.now(),
'visitor': '{}: {}'.format(remote_addr, user_agent),
})
def fetch_visits(limit):
visits_ref = fs_client.collection('Visit')
visits = (v.to_dict() for v in visits_ref.order_by('timestamp',
direction=firestore.Query.DESCENDING).limit(limit).stream())
return visits
Основная функция root()
остается такой же, как и файл шаблона index.html
. Дважды проверьте свои изменения, сохраните, разверните и проверьте.
6. Подведение итогов/очистка
Развернуть приложение
Повторно разверните приложение с помощью gcloud app deploy
и убедитесь, что приложение работает. Теперь ваш код должен соответствовать тому, что находится в репозитории Модуля 6 (или версии 2.x, если вы этого предпочитаете).
Если вы приступили к этой серии, не пройдя ни одной из предыдущих работ по коду, само приложение не изменится; он регистрирует все посещения главной веб-страницы ( /
) и выглядит так, если вы посетили сайт достаточное количество раз:
Поздравляем с завершением дополнительной миграции Модуля 6. Вероятно, это одна из, если не последняя, миграция, которую вы можете выполнить в отношении хранилища данных App Engine. Одна из альтернативных вариантов миграции, которую вы можете рассмотреть, — это контейнеризация вашего приложения для Cloud Run, если вы еще этого не сделали (см. модули 4 и 5, ссылки на кодовые лаборатории ниже).
Дополнительно: очистка
А как насчет очистки, чтобы избежать выставления счетов до тех пор, пока вы не будете готовы перейти к следующей лаборатории кода миграции? Как существующие разработчики, вы, вероятно, уже в курсе ценовой информации App Engine .
Необязательно: отключить приложение
Если вы еще не готовы перейти к следующему руководству, отключите приложение , чтобы избежать расходов. Когда вы будете готовы перейти к следующей лаборатории кода, вы можете снова включить ее. Пока ваше приложение отключено, оно не будет получать трафик, за который взимается плата, однако вы можете получить счет за использование Firestore, если оно превышает бесплатную квоту , поэтому удалите достаточно трафика, чтобы попасть под этот лимит.
С другой стороны, если вы не собираетесь продолжать миграцию и хотите полностью удалить все, вы можете закрыть свой проект .
Следующие шаги
Помимо этого руководства, вы можете рассмотреть еще несколько примеров кода модуля миграции:
- Модуль 7. Очереди задач App Engine Push (требуется, если вы используете очереди задач [push])
- Добавляет
taskqueue
задач App Engine в приложение модуля 1. - Готовит пользователей к переходу на облачные задачи в модуле 8.
- Добавляет
- Модуль 4. Переход на Cloud Run с помощью Docker
- Контейнеризируйте свое приложение для работы в облаке. Работайте с Docker.
- Эта миграция позволяет вам остаться на Python 2.
- Модуль 5. Переход на Cloud Run с помощью Cloud Buildpacks
- Контейнеризируйте свое приложение для работы в облаке. Запускайте с помощью Cloud Buildpacks.
- Вам не нужно ничего знать о Docker, контейнерах или
Dockerfile
. - Требуется, чтобы ваше приложение уже было перенесено на Python 3 (Buildpacks не поддерживает Python 2).
7. Дополнительные ресурсы
Проблемы и отзывы о модулях миграции App Engine
Если вы обнаружите какие-либо проблемы с этой кодовой лабораторией, сначала найдите свою проблему, прежде чем подавать заявку. Ссылки для поиска и создания новых задач:
Миграционные ресурсы
Ссылки на папки репозитория для Модуля 3 (НАЧАЛО) и Модуля 6 (ФИНИШ) можно найти в таблице ниже. Доступ к ним также можно получить из репозитория для всех миграций App Engine , которые можно клонировать или загрузить в виде ZIP-файла.
Кодлаб | Питон 2 | Питон 3 |
( код ) | ||
Модуль 6 | (н/д) |
Ресурсы App Engine
Ниже приведены дополнительные ресурсы, касающиеся этой конкретной миграции:
- Ссылки на Python Cloud Datastore и Cloud Firestore
- Переход на Python 3 и среду выполнения нового поколения GAE
- Общий