Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Лучшие практики для Cloud Firestore

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Используйте рекомендации, перечисленные здесь, в качестве краткого справочника при создании приложения, использующего Cloud Firestore.

Местоположение базы данных

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

Чтобы максимизировать доступность и надежность приложения, выберите расположение в нескольких регионах и разместите важные вычислительные ресурсы как минимум в двух регионах.

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

Идентификаторы документов

  • Избегайте идентификаторов документов . и .. .
  • Избегайте использования косой черты / в идентификаторах документов.
  • Не используйте монотонно увеличивающиеся идентификаторы документов, такие как:

    • Customer1 , Customer2 , Customer3 , ...
    • Product 1 , Product 2 , Product 3 , ...

    Такие последовательные идентификаторы могут привести к появлению горячих точек , влияющих на задержку.

Имена полей

  • Избегайте следующих символов в именах полей, поскольку они требуют дополнительного экранирования:

    • . период
    • [ левая скобка
    • ] правая скобка
    • * звездочка
    • ` обратная галочка

Индексы

  • Избегайте использования слишком большого количества индексов. Чрезмерное количество индексов может увеличить задержку записи и увеличить затраты на хранение записей индекса.

  • Имейте в виду, что индексирование полей с монотонно возрастающими значениями, такими как временные метки, может привести к появлению горячих точек , которые влияют на задержку для приложений с высокой скоростью чтения и записи.

Исключения индекса

Для большинства приложений вы можете полагаться на автоматическое индексирование, а также любые ссылки на сообщения об ошибках для управления вашими индексами. Однако вы можете добавить исключения для одного поля в следующих случаях:

Кейс Описание
Большие строковые поля

Если у вас есть строковое поле, которое часто содержит длинные строковые значения, которые вы не используете для запросов, вы можете сократить расходы на хранение, исключив это поле из индексации.

Высокая скорость записи в коллекцию, содержащую документы с последовательными значениями

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

Например, в случае использования Интернета вещей с высокой скоростью записи коллекция, содержащая документы с полем метки времени, может приблизиться к пределу в 500 операций записи в секунду.

Поля TTL

Если вы используете политики TTL (время жизни) , обратите внимание, что в поле TTL должна быть отметка времени. Индексирование полей TTL включено по умолчанию и может повлиять на производительность при более высоких скоростях трафика. Рекомендуется добавить исключения для отдельных полей для полей TTL.

Большой массив или поля карты

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

Операции чтения и записи

  • Избегайте записи в документ чаще одного раза в секунду. Дополнительные сведения см. в разделе Обновления одного документа .

  • Используйте асинхронные вызовы, где это возможно, вместо синхронных вызовов. Асинхронные вызовы минимизируют влияние задержки. Например, рассмотрим приложение, которому требуется результат поиска документа и результаты запроса перед отображением ответа. Если поиск и запрос не имеют зависимости данных, нет необходимости синхронно ждать завершения поиска, прежде чем инициировать запрос.

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

Транзакции повторяются

Пакеты SDK и клиентские библиотеки Cloud Firestore автоматически повторяют неудачные транзакции для устранения временных ошибок. Если ваше приложение обращается к Cloud Firestore через REST или RPC API напрямую, а не через SDK, ваше приложение должно реализовать повторные попытки транзакций для повышения надежности.

Обновления в реальном времени

Для наилучшей производительности прослушивателя моментальных снимков делайте документы небольшими и контролируйте скорость чтения ваших клиентов. Следующие рекомендации содержат указания по максимальному повышению производительности. Превышение этих рекомендаций может привести к увеличению задержки уведомлений.

Рекомендация Подробности
Уменьшить отток прослушивателей моментальных снимков

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

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

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

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

Ограничение прослушивателей моментальных снимков на клиента

100

Держите количество прослушивателей моментальных снимков на клиенте ниже 100.

Ограничить скорость записи коллекции

1000 операций в секунду

Держите скорость операций записи для отдельной коллекции ниже 1000 операций в секунду.

Ограничьте количество push-уведомлений для отдельных клиентов

1 документ в секунду

Держите скорость документов, которые база данных отправляет отдельному клиенту, ниже 1 документа в секунду.

Ограничьте глобальную частоту отправки клиентов

1 000 000 документов в секунду

Поддерживайте скорость документов, которые база данных отправляет всем клиентам, ниже 1 000 000 документов в секунду.

Это мягкий предел. Cloud Firestore не мешает вам превысить этот порог, но сильно влияет на производительность.

Ограничьте полезную нагрузку отдельных документов

10 КиБ/сек

Максимальный размер документа, загружаемого отдельным клиентом, должен быть ниже 10 КиБ/с.

Ограничьте глобальную полезную нагрузку документа

1 ГиБ/сек

Сохраняйте максимальный размер документа, загружаемого всеми клиентами, на уровне менее 1 ГиБ/с.

Ограничить количество полей в документе

100

В ваших документах должно быть менее 100 полей.

Ознакомьтесь со стандартными ограничениями Cloud Firestore

Помните о стандартных ограничениях для Cloud Firestore .

Обратите особое внимание на ограничение в 1 запись в секунду для документов и ограничение в 1 000 000 одновременных подключений к базе данных. Это мягкие ограничения, которые Cloud Firestore не помешает вам превысить. Однако превышение этих ограничений может повлиять на производительность в зависимости от общей скорости чтения и записи.

Проектирование в масштабе

Следующие рекомендации описывают, как избежать ситуаций, вызывающих конфликты.

Обновления в одном документе

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

Высокая скорость чтения, записи и удаления в узком диапазоне документов

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

  • Создает новые документы с очень высокой скоростью и выделяет собственные монотонно возрастающие идентификаторы.

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

  • Создает новые документы с высокой скоростью в коллекции с небольшим количеством документов.

  • Создает новые документы с монотонно растущим полем, например меткой времени, с очень высокой скоростью.

  • Удаляет документы в коллекции с высокой скоростью.

  • Записывает в базу данных с очень высокой скоростью без постепенного увеличения трафика.

Избегайте пропуска удаленных данных

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

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

docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
delete_batch.commit()

Каждый раз, когда этот запрос выполняется, он просматривает записи индекса для created поля во всех недавно удаленных документах. Это замедляет запросы.

Чтобы повысить производительность, используйте метод start_at , чтобы найти лучшее место для начала. Например:

completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
    {'created': completed_items.get('last_completed')}).order_by(
        'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
  last_completed = doc.get('created')

if last_completed:
  delete_batch.update(completed_items.reference,
                      {'last_completed': last_completed})
  delete_batch.commit()

ПРИМЕЧАНИЕ. В приведенном выше примере используется монотонно увеличивающееся поле, которое является антишаблоном для высоких скоростей записи.

Наращивание трафика

Вы должны постепенно наращивать трафик к новым коллекциям или лексикографически близким документам, чтобы дать Cloud Firestore достаточно времени для подготовки документов к возросшему трафику. Мы рекомендуем начинать с максимум 500 операций в секунду для новой коллекции, а затем увеличивать трафик на 50% каждые 5 минут. Вы также можете увеличить свой трафик записи, но помните о стандартных ограничениях Cloud Firestore . Убедитесь, что операции распределены относительно равномерно по всему диапазону клавиш. Это называется правилом «500/50/5».

Перенос трафика в новую коллекцию

Постепенное наращивание особенно важно, если вы переносите трафик приложения из одной коллекции в другую. Простой способ справиться с этой миграцией — прочитать из старой коллекции, а если документ не существует, то прочитать из новой коллекции. Однако это может привести к резкому увеличению трафика лексикографически близких документов в новой коллекции. Cloud Firestore может быть не в состоянии эффективно подготовить новую коллекцию к увеличению трафика, особенно если она содержит мало документов.

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

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

Параллельное чтение

Чтобы реализовать параллельное чтение при переносе трафика в новую коллекцию, сначала выполните чтение из старой коллекции. Если документ отсутствует, то читать из новой коллекции. Высокая скорость чтения несуществующих документов может привести к появлению горячих точек, поэтому обязательно постепенно увеличивайте нагрузку на новую коллекцию. Лучшая стратегия — скопировать старый документ в новую коллекцию, а затем удалить старый документ. Постепенно увеличивайте количество параллельных чтений, чтобы Cloud Firestore мог обрабатывать трафик к новой коллекции.

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

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

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

Обратите внимание, что вы не сможете легко выполнить откат, если не выполните двойную запись как старых, так и новых объектов на этапе миграции. Это приведет к увеличению затрат на Cloud Firestore.

Предотвращение несанкционированного доступа

Предотвратите несанкционированные операции с вашей базой данных с помощью правил безопасности Cloud Firestore. Например, с помощью правил можно избежать ситуации, когда злоумышленник неоднократно загружает всю вашу базу данных.

Узнайте больше об использовании правил безопасности Cloud Firestore .