Upgrade to Pro — share decks privately, control downloads, hide ads and more …

運用6年目・500万人が使うアプリのDBをSQLiteからFirestoreに移行した話(iO...

Avatar for Ryo Iida Ryo Iida
September 18, 2021

運用6年目・500万人が使うアプリのDBをSQLiteからFirestoreに移行した話(iOSDC 2021)

Avatar for Ryo Iida

Ryo Iida

September 18, 2021
Tweet

More Decks by Ryo Iida

Other Decks in Technology

Transcript

  1. はじめに - 自己紹介 飯田 諒(@aviciida) • mikanのiOSエンジニア ◦ 🍊 mikan歴

    3年(since 2018/9) ◦ 🍎 iOSエンジニア歴 2年 (since 2019/5) • PM/分析もやってます! • ユーザー目線でプロダクト作るの好き • Twitter活発です!@aviciida 2
  2. • iOSエンジニア • Androidエンジニア • サーバーサイド・インフラ エンジニア • デザイナー (

    時期を見て、週1回程度の出社を想定) 社員 (まずは副業からでもOK) ※基本リモート勤務 ご連絡はこちらから (Twitter DMでも!󰢏) https://mikan.link/carrers mikanは絶賛採用中です! 5
  3. アジェンダ ① なぜSQLiteからFirestoreに移行したのか? ・なぜ組み込み型SQLiteが採用されていた? ・当時のツラミ ・Firestoreを採用した理由 ・移行によって変わること ② 実際の移行の話 ・全体観

    ・ダブルライト ・マイグレーション ・クライアント側のreadロジック移行 ③振り返って ・うまくいったこと / やればよかったこと ・実際Firestore使ってみてどう? ・今回の学び 8
  4. アジェンダ ① なぜSQLiteからFirestoreに移行したのか? ・なぜ組み込み型SQLiteが採用されていた? ・当時のツラミ ・Firestoreを採用した理由 ・移行によって変わること ② 実際の移行の話 ・全体観

    ・ダブルライト ・マイグレーション ・クライアント側のreadロジック移行 ③振り返って ・うまくいったこと / やればよかったこと ・実際Firestore使ってみてどう? ・今回の学び 9
  5. データの同期・移行が不可能、もしくはかなり大変 • 異OS間では不可能 ◦ AndroidはRealmを使っている && スキーマも違うため • 同OS間では”一応”可能(だがめちゃ大変) ◦

    まず問い合わせいただく→CSチームがS3に入る→旧端末のバケッ トから新端末のバケットにDBファイルをドラッグ&ドロップする →ユーザーさんがアプリ内でデータの復元をする その他 • 生SQLを書く時に、エラーがランタイムにしかわからない • マスターがないため、あらゆるバージョンを想定する必要あり 当時のツラミ - 組み込み型SQLite 12
  6. データ構造の一部が負債化 • ある日、本としては1冊だけど、複数のBookを持 つ教材が登場 ◦ 1教材 = 複数 Books があり得る状態に

    • 単体Bookと複数Booksに対応しなければならず、 コードにif文が大量発生し、負債に 14 before 1教材 = 1book after 1教材 = 複数books 当時のツラミ - その他、旧DBについて book table
  7. mikanの求めていた要件 / 当時の状況にマッチしていた • オフライン対応 • データの移行・同期 • サーバーサイドが薄く、クライアントサイドが厚いチーム体制 ◦

    上記要件を、サーバーレスに実現できるのが魅力的 当時の候補 • API作る: サーバーサイドのリソースの関係で厳しい...! • Realm: サーバーサイドで扱える言語がmikan(Go)とマッチしない Firestoreを採用した理由 15
  8. ① 組み込み型→ネットワーク型へ • 同じIDでログインすれば、簡単にデータ移行可能に • 基本はオフライン対応可能だけど、最初は通信必要に ② RDB→KVSへ • カラムの追加が簡単に

    • 集計が弱いため、サマリーデータを持つ必要が出てくる ◦ 各単語の記憶度を元にした、各教材の進捗度 ◦ モデルのそのまま移行というわけにはいかなくなる! Firestoreへの移行によって変わること整理 16 サマリーデータを持っている ドキュメント
  9. アジェンダ ① なぜSQLiteからFirestoreに移行したのか? ・なぜ組み込み型SQLiteが採用されていた? ・当時のツラミ ・Firestoreを採用した理由 ・移行によって変わること ② 実際の移行の話 ・全体観

    ・ダブルライト ・マイグレーション ・クライアント側のreadロジック移行 ③振り返って ・うまくいったこと / やればよかったこと ・実際Firestore使ってみてどう? ・今回の学び 17
  10. 移行の全体観 18 ローカル SQLite app Phase⓪ 従来 write read app

    Phase① ダブルライト write read Firestore write Phase② マイグレーション Firestore ゴリっと 移行 app Phase③ readロジック移行 Firestore write read 👋 ローカル SQLite GCS ローカル SQLite DBファイルを upload app
  11. Phase① ダブルライト • 基本はクライアントサイドの仕事 • データの書き込みを、SQLiteだけでなく、Firestoreにも • ★ ダブルライト開始日をユーザーごとに保持しておく ◦

    マイグレーションの際、ダブルライト以降のデータ は対象にしないようにするため ◦ ユーザーのアップデートに依存してしまい、開始タ イミングがバラバラなため 19 app write read Firestore write ローカル SQLite
  12. 1. client: マイグレーション対象かどうかを判断 2. client: 自分のSQLiteファイルをGoogle Cloud Storageにアップロード 3. client:

    自分のステータスを「マイグレーション待ち」に変更 4. server: ステータスが「待ち」のユーザーに対してマイグレーションを実行 22 DBファイルをuploadするコード Phase② マイグレーション
  13. Phase③ readロジック移行 • クライアント側の最後の大仕事 • 読み込みロジックをSQLiteからFirestoreに移行 ◦ これ以降はFirestoreで書き込み/読み込みが成立し、 SQLiteの依存からは脱却 •

    大変なところ ◦ 同期処理→非同期処理への書き換え ◦ RDB→KVSという変更によって、データの持ち方も変更 ▪ 合わせてコアの学習機能のロジックも少し変更 ◦ DBの書き込み・読み取りロジックが元々クライアント サイドに寄っていたため、対象ファイルが膨大... 23 app Firestore write read 👋 ローカル SQLite
  14. アジェンダ ① なぜSQLiteからFirestoreに移行したのか? ・なぜ組み込み型SQLiteが採用されていた? ・当時のツラミ ・Firestoreを採用した理由 ・移行によって変わること ② 実際の移行の話 ・全体観

    ・ダブルライト ・マイグレーション ・クライアント側のreadロジック移行 ③振り返って ・うまくいったこと / やればよかったこと ・実際Firestore使ってみてどう? ・今回の学び 26
  15. 自前で集客して、パブリックベータを実施できた。 うまくいったこと / やってよかったこと 1/3 27 • Why: iOSの段階的リリースは、実際は段階 的ではない問題

    ◦ 少数に実際に使ってほしい • 集客はLine@やpush通知 • 社内で潰せなかった不具合がたくさん潰せた ◦ 色んなユーザーのデータで触ってもらえ たおかげ • ただ、600人以上はなかなか集まらず...
  16. うまくいったこと / やってよかったこと 3/3 最小単位のログを別のところで貯めておく • mikanでいうと「1単語ごとの学習ログ」 ◦ 2021/9/17 18:50

    に、appleという単語の問題を解いて、不正解 ◦ みたいな • もし不具合などで「学習履歴」や「学習進捗」のデータが消えても、 そのログがあればサマライズして、復元できる 29
  17. 難しかったところ・後悔 3/4 ABテストをできるならやるべきだった やるべき理由 • 数字が上がったのか、下がったのかの判断を正しくするため ◦ 継続率は時期要因にも左右されるので、同時期にABしてないと、 正しく分析できない •

    パブリックベータの人数確保も簡単だった 方法 • DBを触っているVCを全部複製して、片方をDB刷新版にする ◦ 入口から分けてあげると「従来の世界」と「DB刷新の世界」を分 けられる。 33
  18. 一度に多くの問題を解決しない方がいい 今回解決しようとした課題は大きく分けると以下 • OS間のデータ移行ができない ◦ SQLite ⇔ Realmのconverterを作る • 同OSでデータ同期ができない

    ◦ 今のデータ構造・スキーマのままFirestoreに移行する • アプリのデータ構造がしんどい ◦ SQLite、Realmのままデータ構造だけ変える 難しかったところ・後悔 4/4 35
  19. Firestore実際使ってみて - 難しいところ 3/3 40 • 不整合なくデータを入れていくために必要な学習コストが高い ◦ security rules,

    transaction, batch, increment valuesなど • 値段が高い ◦ 今はFirestoreだけで25万円 ◦ AWSのRDS使っていた時は、EC2やロードバランサー含め15万ほど
  20. データの構造は最初にしっかり設計しよう! • book > chapter > word の構造じゃなくて book >

    chapter, wordの構造に ◦ chapterとwordを同じ階層に置く ◦ 👉 book内の全wordを取得するのがもっと高 速化してた。 • 後から変更しづらいので、最初の設計が大事。 プロジェクトでの学び・アドバイス 3/4 43 こんな感じにしておけば...!
  21. 改めて: mikanは絶賛採用中です! • iOSエンジニア • Androidエンジニア • サーバーサイド・インフラ エンジニア •

    デザイナー ( 時期を見て、週1回程度の出社を想定) 社員 (まずは副業からでもOK) ※基本リモート勤務 ご連絡はこちらから (Twitter DMでも!󰢏) https://mikan.link/carrers 45