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

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

Ryo Iida
September 18, 2021

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

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