Ловушка JOIN в Firestore
Вы сталкиваетесь с распространенной проблемой Firestore. Ваша функция Firebase выдает ошибку максимального размера пакета (batch size). Вам нужно объединить (JOIN) заказы и клиентов для дашборда. Обычно вы дублируете данные, чтобы решить эту проблему. Но теперь ваши данные устарели и неконсистентны.
Google анонсировал Pipelines API для решения этой проблемы. Он позволяет выполнять операции JOIN между коллекциями без дублирования данных. Некоторые разработчики сообщают о быстром времени выполнения запросов в небольших тестах.
Я потратил неделю на тестирование этого API под высокой нагрузкой. Вот чего не говорит документация.
Высокая стоимость Каждое выполнение pipeline считывает данные из всех задействованных коллекций. JOIN между двумя коллекциями тарифицируется как чтение в обеих. Если вы объединяете две коллекции по 50 000 документов, ваши расходы растут непропорционально. Это не просто линейная стоимость.
Ограничения производительности В моих тестах выполнение pipeline для 10 000 документов заняло 380 мс. Когда я тестировал 100 000 документов, запрос завершился по таймауту через 30 секунд. Вы не решаете проблему, вы просто превращаете ошибку размера пакета в ошибку таймаута.
Проблемы с «холодным стартом» Pipelines создают отдельный контекст выполнения. В serverless-средах, таких как Cloud Functions, это добавляет задержку от 2 до 4 секунд. Ваши пользователи подумают, что приложение работает медленно.
Pipelines API — это инструмент для прототипирования или работы с небольшими коллекциями (до 5 000 документов). Это не замена реляционной базе данных. Google предоставляет это, чтобы помочь вам оставаться в экосистеме Firebase, вместо того чтобы переходить на PostgreSQL или Spanner.
Если вы используете Pipelines, следуйте этим правилам:
• Проверяйте размер коллекции. Если коллекция превышает 20 000 документов, сначала рассчитайте стоимость JOIN. • Ограничивайте сложность. JOIN между тремя и более коллекциями — плохой знак. • Еженедельно отслеживайте расходы на чтение. Чтения через Pipelines отображаются в счетах иначе. • Сохраняйте денормализованные данные. Используйте Pipelines как дополнение, а не полную замену. • Тестируйте на реальном трафике. Бенчмарки на малоактивных коллекциях не отражают реальность продакшена.
Не используйте «пластырь», чтобы избежать принятия важного архитектурного решения.
Как вы обрабатываете связи в Firestore? Используете денормализацию или JOIN на стороне клиента? Расскажите в комментариях.
