본문 바로가기

Dev/안드로이드

[TIL] 24.06.04 Firebase의 Realtime Database와 Cloud Firestore


 최종 프로젝트를 한창 진행 중에 있는데, Firebase를 이용한 원격 DB를 도입하게 되면서 고민해야 하는 부분이 생겼다.
처음에 당연히 DB의 변화를 실시간으로 감지해서 UI에 변화를 발생시켜야 하는 부분이 많을 줄 알고(일종의 flow를 내려주는 격), Realtime Database를 채택했는데 앱의 윤곽이 잡히고 나니 생각보다 그런 부분이 적은듯 했다.

 

그래서 어떤 것을 도입할 지 공식문서를 읽어보면서, 확실하게 결정해서 리팩터링을 진행하기로 했다.
Choose a database: Cloud Firestore or Realtime Database  |  Firebase (google.com)

 

데이터베이스 선택: Cloud Firestore 또는 실시간 데이터베이스  |  Firebase

5월 14일, Google I/O에서 Firebase를 다시 만나보세요. 지금 등록하기 의견 보내기 데이터베이스 선택: Cloud Firestore 또는 실시간 데이터베이스 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐

firebase.google.com

 

 

 

 Firebase에서는 두 가지 DB를 제공하는데, Cloud Firestore와 Realtime Database이다. 설명에도 나와있듯이, Realtime Database는 Firebase의 클래식한 JSON DB이며, 간단한 데이터들을 낮은 레이턴시로 동기화 하는 것에 유리하다. Cloud Firestore는 비교적 최신에 나온 DB인데, 기존 Realtime Database의 약점이었던, 복잡한 쿼리나 확장성, 높은 가용성 등에 메리트가 있다고 한다. 물론 이 또한 낮은 레이턴시의 동기화나 오프라인 데이터 액세스를 제공한다고 한다.

 

 

 

 Data model - 둘 다 NoSQL이며, Cloud Firestore는 document의 컬렉션으로, Realtime Database는 단일 JSON 트리로 저장하게 된다. 따라서 복잡한 형태의 데이터를 저장할수록, Cloud Firestore 쪽에 유리하다.

 

 

 

 Realtime and offline support - 둘 다, 모바일 환경에 최적화된 realtime SDK를 가지고 있고, 로컬 캐싱을 통한 오프라인 상태의 앱을 지원하는 수단도 보유하고 있다. Cloud Firestore의 경우, 웹 클라이언트에서의 오프라인 지원도 가능하다는데 나는 안드로이드 앱을 개발하는 입장이기 때문에 이 부분에서는 큰 차이를 못 느낄 것 같다.

 

 

 

 Presence - 클라이언트의 온라인/오프라인 상태를 체크하는 기능인 듯 하다. 네트워크 연결 상태 변화를 감지할 수 있는 것 같고, Realtime Database에서는 이를 지원하고 있다. 하지만 Cloud Firestore에서는 이를 지원하지 않으며, Realtime Database와의 연동을 통해 어느정도 이용가능한 것 같다. 이런 기능을 자체적으로 지원한다면, 개발자의 수고를 한층 덜어주긴 한다.

 

 

 

 Querying - 사실 이 부분이 좀 크게 다가온 것 같다. Realtime Database의 쿼리는 단순한 형태로만 제공되고, 하나의 프로퍼티에 대한 정렬 혹은 필터링만을 지원한다. 이마저도 정렬이든 필터링이든 하나만 이용할 수 있다. 대신 deep query 형태로 결과 값이 subtree 형태로 온다는 점은 어느정도 유리한 부분이 있다(애초에 구조가 단일 JSON 트리이기 때문에).

 Cloud Firestore에서는 복잡한 쿼리나 복합 쿼리도 지원하고, 대체로 일반적인 DB에서 보이는 성질을 가지고 있다. indexed query를 이용하기 때문에 퍼포먼스가 데이터셋의 크기가 아닌, 결과의 크기에 의존한다. 

 앱에서 Realtime Database를 도입했을 때, 여러 속성에 대한 필터링을 걸고 싶었는데, 자체적으로 지원하지 않아 꽤 난감했었다. 예를 들면 특정 반려견 id를 가진 산책 데이터 중, 특정 기간 내에 속하는 데이터들만 가져오고 싶은데, Realtime Database에서는 둘 중의 하나의 조건만 필터링해서 내려 보내주었다. 그래서 클라이언트 상에서 추가적인 필터링이 필요해서 퍼포먼스에 대한 우려도 좀 생겼었다.

 

 

 

 Writes and transactions - 쓰기 작업 시에, Cloud Firestore는 set과 update 동작 외에 배열이나 숫자 연산자 같은 고급 transformation들을 지원한다는데, 이는 써보기 전까지는 와닿지 않는 것 같다. 클라이언트에서 전적으로 모핑을 끝낼 필요가 없다는 말인가? 그리고 Cloud Firestore의 경우 DB의 모든 부분에서 쓰기와 읽기 작업이 atomic 하게 이뤄지지만, Realtime Database에서는 특정 데이터 서브트리에서만 atomic 하다고 한다. 아마 특정 데이터 서브트리 라는게 값을 가지는 속성들을 일컫는 것이 아닐까 하는데, 그렇다면 atomic한 동작이 보장돼야 하는 부분들에 대해서는 모두 지원을 하고 있을 것으로 생각된다.

 

 

 Reliability and performance - 이 부분도 중요한 부분이다. Cloud Firestore는 multi-region solution으로 자동 확장되어, 어느정도 일관된 퍼포먼스와 신뢰성이 보장된다. Realtime Database는 단일 지역 데이터 센터만을 이용하기 때문에, 안정성은 조금 부족하지만 퍼포먼스는 오히려 우수하다. 어느정도 데이터 센터와의 가까운 물리적 거리를 보장할 수 있고, 가벼운 데이터 변경이 자주 발생하며 빠른 클라이언트의 반응을 기대할 경우 Realtiem Database가 유리함을 알 수 있다.

 

 

 

 Uptime - Cloud Firestore 쪽이 극한의 업타임을 보장하고 있다. 그래서 금융 결제 앱 등은 Cloud Firestore를 사용할 것을 권장하고 있다.

 

 

 

 Scalability - Cloud Firestore는 Scaling이 자동으로 일어난다고 한다. 그래서 그냥 방치했을 때는 동시 연결이나 초 당 쓰기량은 Cloud Firestore 쪽이 우세하다. 다만 Realtime Database에서도 직접 복수 개의 데이터베이스를 이용해 확장한다면 이는 어느정도 커버할 수 있는 문제로 보인다.

 다른 차이가 있다면 Cloud Firestore는 각 문서나 인덱스에 대해 쓰기율이 제한되어 있고, Realtime Database는 그렇지 않다는 점이다. 만약 특정 데이터 하나가 엄청 자주 바뀌어야 하는 경우에는 Cloud Firestore 쪽에서는 문제가 발생할 수도 있겠다는 생각이 들었다. 대신 일반적인 케이스에서는 Cloud Firestore 쪽이 사용하기 편리할 것 같다.

 

 

 

 Security - 둘 다 보안을 위한 rule을 설정하게 되고, non-cascading이냐 cascading이냐의 차이를 보인다. 아마 non-cascading이면 조금 번거롭지만 디테일한 설정이 가능할 것이고, cascading은 그 반대인 차이정도가 있을 것 같다. 그리고 Cloud Firestore에서는 rule을 통해 쿼리도 제한할 수 있는 것으로 보인다.

 

 

 Pricing - 앱이 커져야 이 부분을 저울질 해보겠지만, 미리 확인해 볼 필요도 있다. Cloud Firestore는 작업 단위로 비용이 청구되지만 비용이 대체로 저렴하고, Realtime Database는 대역폭과 저장량에 대한 비용만 청구하지만 비용이 더 높다고 한다. 작업 단위에 따라 비용이 청구될 수 있다는 걸 보고, 조금 염려돼서 어느정도 선까지가 무료인지 찾아보았다.

 

 

  이 정도면, 아직 걱정할 정도는 아닌 것 같다. 

 

 

 

 

 전반적으로 봤을 때, Realtime Database가 가지는 레이턴시 이점도 어느정도 있지만, 비교적 최근에 나온 Cloud Firestore 쪽이 좀 더 advanced 한 기능을 많이 제공하고 편해보였다. 특히 앱 내에 트랜잭션 레이턴시를 극한까지 낮춰야하는 부분이 없고, 오히려 복합 쿼리를 이용해 데이터를 가져오는 기능이 많이 제공되어야 했기 때문에 Cloud Firestore를 사용하는 것으로 가닥을 잡게 됐다.