7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Firestoreを本番で半年運用したアーキテクチャ:その② 〜PubSubとCloud Functionsを使って、FirestoreのCollectionをマイクロサービスに見立てた話〜

Last updated at Posted at 2019-03-03

これは?

Firebase Meetup #10 で 「Firestore導入前に検討したかったベスト5」 というテーマで発表したアーキテクチャ部分の話その2。(めちゃくちゃゆっくりな更新...)

①Firestoreを中心に据えた全体設計のコンセプト
②PubSubとCloud Functionsを使って、FirestoreのCollectionをマイクロサービスに見立てた話 ←今回
③パフォーマンスの劣化対策として、CacheのCollectionを作った話

トライしたこと

まず、どんなトライをしたのか説明していきます。
この中で、今回お話するのが、赤丸をした部分です。

image.png

ここでは何をしているかというと、
1つのObjectを、PubSubにPublishするんですが、そのPublishされたもの(Topicと呼ばれます)に、複数のSubscriptionを付与しています。
そのSubscriptionは、Cloud Functionsなど、別々のアプリケーションに紐付けられてます。

つまり、何か新しいObjectがPublishされると、Cloud Functionsやらが、同時に並行して処理をはじめます。

その時に、それぞれのアプリケーションが、それぞれFirestoreの 1つのcollection に書き込みます。
つまり、そのcollectionにデータを入れるために、どんな処理が必要か、という責務に集中したアプリケーション群を並列に動かしました。

これは何でか、というと、

FirestoreはJOINできない = つまり、1つ1つのcollectionが別のデータベースのように振る舞っている と思ったからです。

もちろん、writeBatchを使ったり、transactionを使ったりして、リレーションを保つ方法はあります。

でも、そうやって自らに制約をどんどん課していくと、Firestoreの本来の力を引き出しきれなくなるのでは、と思いました。

というのも、 並列に動いて一時的にNullableになったとしても、本来、スキーマレスなのですべての値がNullableになりえるので、そういう設計をしていないといけないし、
何よりリアルタイム性が高いので、そのNullableな状態を許容した上で、整合性取れた時点で画面にリアルタイムに表示されていくべき
だよな、
そう考えたわけです。

これはイメージ的には、それぞれ1アプリケーションと1Collectionのひとまとまりが、1マイクロサービスのような形になっています。

ちなみに、この設計にできたのは、そもそも僕が、最初にFirestoreを使い始めるときに、RDBのようにある程度正規化していたためです。
最初にその設計になっていないと、やろうとしても他のデータが混ざってできない気がします。

良かったこと

当たり前ですが、実装がめちゃくちゃシンプルになって、かなり突貫でつくっていたんですが、汚染なく、ステートレスになりました。

ただ、途中から変えたので、元々あった部分はステートフルが残っていて、最初にこの形にしていなかったのを後悔していました。。

悪かったこと

当たり前ですが、並列性を担保すると、同期が取れにくくなります。

ということは、データの入り方によって種々のパターンが発生してしまいます。

本来nullable、ということに基づいて設計できていれば問題ないのですが、
それをチームでちゃんと理解を浸透させないとリスクを生む、というのが1点。

もう一つは、ただデータを保存するだけならいいけれども、そのデータを元にすぐに他の処理(副作用)を起こそう、という時に、
1つのcollectionのデータだけでは完結しない場合があります。

そうすると、複数のcollectionのデータをまたがるので、こうなるとFirestoreはめちゃくちゃ弱い。

Firestoreにデータが入ってから何かするぞ、というときに、1つのcollectionだけウォッチすればいいわけではないので、
こういう感じになると、複数のcollectionをウォッチしたり、専用に新たにcollectionつくったり、
めちゃくちゃにややこくなるので、
だったら最初っから同期でつくった方がよい!となります。

僕らはそのケースに当てはまったので、突貫でつくったものをリファクタするときに、同期式へ書き換えていったのでした。

わりとこの辺は要件次第ですが、ハマれば強いとおもいました。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?