Firestore JOIN의 함정

흔히 발생하는 Firestore 문제에 직면하게 됩니다. Firebase 함수에서 최대 배치 크기 오류(maximum batch size error)가 발생합니다. 대시보드를 위해 주문(orders)과 고객(customers) 데이터를 조인해야 합니다. 보통 이를 해결하기 위해 데이터를 중복 저장하지만, 이제 데이터는 최신 상태가 아니며 일관성도 깨지게 됩니다.

Google은 이를 해결하기 위해 Pipelines API를 발표했습니다. 데이터를 중복 저장하지 않고도 컬렉션 간의 JOIN 작업을 수행할 수 있게 해줍니다. 일부 개발자들은 소규모 테스트에서 빠른 쿼리 속도를 보고하기도 합니다.

저는 과부하 상태에서 이 API를 일주일 동안 테스트했습니다. 문서에는 나와 있지 않은 사실을 알려드립니다.

  1. 높은 비용 모든 파이프라인 실행은 관련된 모든 컬렉션에서 데이터를 읽습니다. 두 컬렉션 간의 JOIN은 두 컬렉션 모두의 읽기 비용을 청구합니다. 50,000개의 문서가 있는 두 컬렉션을 조인하면 비용이 급격히 증가합니다. 이는 단순히 선형적으로 증가하는 비용이 아닙니다.

  2. 성능 한계 제 테스트 결과, 10,000개의 문서를 대상으로 한 파이프라인은 380ms가 걸렸습니다. 100,000개의 문서를 테스트했을 때는 쿼리가 30초 만에 타임아웃되었습니다. 문제를 해결하는 것이 아니라, 배치 오류를 타임아웃 오류로 바꾸고 있을 뿐입니다.

  3. 콜드 스타트 문제 파이프라인은 별도의 실행 컨텍스트를 생성합니다. Cloud Functions와 같은 서버리스 환경에서는 이로 인해 2~4초의 지연이 추가됩니다. 사용자는 앱이 느리다고 느낄 것입니다.

Pipelines API는 프로토타이핑이나 5,000개 미만의 소규모 컬렉션을 위한 도구입니다. 관계형 데이터베이스를 대체할 수 있는 것이 아닙니다. Google이 이를 제공하는 이유는 사용자가 PostgreSQL이나 Spanner로 이동하는 대신 Firebase 생태계에 머물도록 돕기 위함입니다.

Pipelines를 사용한다면 다음 규칙을 따르십시오:

• 컬렉션 크기를 점검하십시오. 컬렉션이 20,000개를 초과하면 JOIN 비용을 먼저 계산하십시오. • 복잡성을 제한하십시오. 3개 이상의 컬렉션을 조인하는 것은 좋지 않은 신호입니다. • 매주 읽기 비용을 추적하십시오. 파이프라인 읽기 비용은 청구서에 다르게 나타납니다. • 비정규화된 데이터를 유지하십시오. Pipelines를 전체 대체제가 아닌 보조 수단으로 사용하십시오. • 실제 트래픽으로 테스트하십시오. 조용한 컬렉션에서의 벤치마크는 운영 환경의 현실을 반영하지 못합니다.

진정한 아키텍처 결정을 피하기 위해 임시방편을 사용하지 마십시오.

Firestore에서 관계를 어떻게 처리하시나요? 비정규화를 사용하시나요, 아니면 클라이언트 측 조인(client-side joins)을 사용하시나요? 댓글로 알려주세요.

Source: https://dev.to/xu_xu_b2179aa8fc958d531d1/the-firestore-join-trap-what-googles-new-pipelines-api-costs-you-that-nobodys-talking-about-an7