既存サービスに後からR/W Splittingライブラリを入れる時に考えたこと / r-w-splitting

既存サービスに後からR/W Splittingライブラリを入れる時に考えたこと / r-w-splitting

R/W Splittingライブラリを自作する際に考えたことと、
実際に使い始めてどうだったかについて振り返ってみました

B989cc865d53d8e26fdadac99727113c?s=128

Satoshi Kawashima

June 04, 2020
Tweet

Transcript

  1. © - BASE, Inc. 2020/06/04 コネヒトマルシェ オンライン 川島 慧/@nazonohito 既存サービスに後から

    R/W Splittingライブラリを⼊れる時に考えたこと
  2. © - BASE, Inc. Product Division 川島 慧 @nazonohito

  3. © - BASE, Inc. BASEがR/W Splittingを開始してから ちょうど1年経ったので、 ライブラリ製作者の視点から振り返ってみます

  4. © - BASE, Inc. そもそもR/W Splittingとは?

  5. © - BASE, Inc. R/W Splittingとは • Read/Write Splitting •

    マスター/リードレプリカ構成のRDBMSに対して負 荷分散の⽬的でアプリケーションのアクセス先を制 御する • 参照系クエリをリードレプリカに寄せることでマス ターのマシンリソースを有効活⽤できるようになる
  6. © - BASE, Inc. 背景について

  7. © - BASE, Inc. BASEの背景 • サービスの成⻑によってトラフィックの量が増⼤していた • ⼈気ショップのセールによる瞬間的な⾼負荷が発⽣すること もあった

    BASEが今後も安定して成⻑していくために データベースのスケーラビリティが ⼤きな課題になってきた
  8. © - BASE, Inc. それまでのR/W Splitting事情 • CakePHP 公式で⽤意されている仕組みはない •

    リード専⽤ModelやBehaviorによって部分的に実現 していたが、もっと汎⽤的なR/W Splittingライブラ リが必要になってきたので作ることになった • ※コネヒトさんがCakePHP のR/W Splittingライブラリを公開する以前なの で⾃作するしかなかった
  9. © - BASE, Inc. 実装⽅針を考える

  10. © - BASE, Inc. 主な関⼼事 • アクセス先の明⽰的に切り替えを可能にする仕組み が欲しい • 既存の巨⼤なコードベースにどうシームレスに導⼊

    していくか • ⼤規模な切り替えをどう安全に実現していくか
  11. © - BASE, Inc. ユースケースを想定して設計する • 既存コードに対するR/W Splittingの適⽤⽅法をある 程度類型化して考えを整理する

  12. © - BASE, Inc. ユースケースの想定

  13. © - BASE, Inc. ユースケース1:スロークエリを狙い撃ちした部分適⽤ • NewRelicなどのアプリケーション監視からボトル ネックとなっているクエリを発⾒して、それだけを リードレプリカに向ける •

    クエリの実⾏負荷は特定のクエリに偏在しているの で、最も費⽤対効果の⾼い適⽤⽅法
  14. © - BASE, Inc. ユースケース2:コントローラアクション単位で適⽤ • コントローラアクション単位でリードレプリカに向 ける • 参照系コントローラアクションなど、参照クエリし

    か無いと分かっている箇所にまとめてリードレプリ カに向ける
  15. © - BASE, Inc. ユースケース3:アプリケーション単位で適⽤ • アプリケーション単位で全てのDBアクセスをデフォ ルトではリードレプリカへ向けてしまうドラス ティックな適⽤ •

    更新系クエリ全てに対して明⽰的にマスターへ向け てやる必要がある • 最も負荷分散の効果が⾼いが、更新系クエリの⾒逃 しやレプリケーション遅延による影響が危惧される
  16. © - BASE, Inc. 3つの想定ユースケース • 後者のユースケースほど適⽤範囲が広くて適⽤が⼤変 • 初期導⼊時に広範囲のコードを読む必要がある •

    後の改修の影響を受けやすいリスクが有る 最初は参照クエリだけだったが、 後の改修で更新クエリが 発⾏されるようになる可能性がある
  17. © - BASE, Inc. 考えたこと • 基本的にはスロークエリを狙い撃ちするアプローチ になると思う • ただDBコネクション数を減らす効果は薄いので、広

    い範囲への適⽤はいずれ避けられないと考えていた
  18. © - BASE, Inc. 部分適⽤ではコネクション数は減らない 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ

    参照クエリ 参照クエリ ͱ͋ΔࢀরΫΤϦ͔͠ൃߦ͠ͳ͍ ίϯτϩʔϥΞΫγϣϯ͕ݺ͹Εͨ࣌ マスター
  19. © - BASE, Inc. 部分適⽤ではコネクション数は減らない 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ

    参照クエリ 参照クエリ ͱ͋ΔࢀরΫΤϦ͔͠ൃߦ͠ͳ͍ ίϯτϩʔϥΞΫγϣϯ͕ݺ͹Εͨ࣌ マスター マスター リードレプリカ スロークエリなので リードレプリカへ ※DBコネクションは計2つ⽣成される
  20. © - BASE, Inc. 部分適⽤ではコネクション数は減らない 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ

    参照クエリ 参照クエリ ͱ͋ΔࢀরΫΤϦ͔͠ൃߦ͠ͳ͍ ίϯτϩʔϥΞΫγϣϯ͕ݺ͹Εͨ࣌ リードレプリカ ※理想的な状態はこっち、DBコネクションは1つ
  21. © - BASE, Inc. 安全装置の実装 • リードレプリカに発⾏してほしくないクエリが実⾏ されかけた場合に、ライブラリ側で検知して⾃動で マスターへ切り替える仕組み •

    リードレプリカに発⾏されてほしくないもの • 更新系クエリ • トランザクション • etc
  22. © - BASE, Inc. 安全装置の実装 Model Switchable Datasource Behavior Switchable

    Mysql (DataSource) SwitchablePDO PDO PDO Master ReadReplica ReadReplica ModelίʔϧόοΫʹΑͬͯ ॻ͖ࠐΈɾ࡟আΛݕ஌ (beforeSave/beforeDelete) τϥϯβΫγϣϯ։࢝Λݕ஌ ߋ৽ܥΫΤϦΛ ਖ਼نදݱͰݕ஌
  23. © - BASE, Inc. R/W Splittingの適⽤

  24. © - BASE, Inc. 適⽤してからしばらくは • 基本的にはスロークエリを狙い撃ちした部分適⽤だ けが使われた • コントローラアクション単位の適⽤はごく⼀部で⾏

    われてきたがほとんど⾏われることはなかった
  25. © - BASE, Inc. ⼀度だけコネクション数が減らしたいタイミングがあった • マスターのコネクションキャパシティの上限が近づ いてコネクション数を減らす必要が出てきた • アプリケーション単位での切り替え(デフォルトで

    リードレプリカに向けて、更新系クエリが投げられ る箇所を明⽰的にマスターへ向ける)を実⾏した • ほとんど参照しか無いと分かっているアプリケー ションだったので⼤丈夫だと判断された
  26. © - BASE, Inc. ドラスティックな切り替えの⽅法 • コードを全部調べ上げてやるのは量的に厳しい • ⾃動テストや⼿動テストで動作確認しつつ、漏れた 部分は安全装置による⾃動切り替えに頼って切り替

    えを実⾏した
  27. © - BASE, Inc. ⼤規模切り替えの結果

  28. © - BASE, Inc. ⼤規模切り替えの結果 • うまくいった ϦϦʔεલ͸ Ϛελʔ:ϦʔυϨϓϦΧͷ ίωΫγϣϯ਺͸

    ͓͓Αͦ3:1 ϦϦʔεޙ͸΄΅1:1΁ ϚελʔͷίωΫγϣϯ਺͸ 1/2ۙ͘·ͰԼ͕Γɺ ٯʹϦʔυϨϓϦΧ͸2ഒʹͳͬͨ
  29. © - BASE, Inc. ⼤規模切り替えの結果 • サービス影響は出さずにコネクションを⼤幅に減ら せた • 参照クエリの殆どがリードレプリカに向いたのでマ

    スターの負荷も下がった • ただし、その裏側では安全装置が凄まじい回数起動 していた • 安全装置によってサービス影響が抑えられていた
  30. © - BASE, Inc. 考察 • ドラスティックな切り替えでも安全装置があれば案 外なんとかなってしまった • ⼈間が頑張らない機械的なアプローチでもいくつか

    条件が重なればこういうアプローチもありうること が分かった ※レプリケーション遅延による更新の反映されていない参照が発⽣するリスクは潜在的にあるが、 Auroraはレプリケーション遅延が発⽣しづらいらしいのでそこで抑えられているのかもしれない
  31. © - BASE, Inc. まとめ • 既存のコードベースに後からR/W Splittingを導⼊し ていく際に考えたことを共有 •

    基本的にはスロークエリを狙い撃ちした部分適⽤で 良さそうだが、コネクション数の削減を⽬指すと⼤ 規模な導⼊は避けられない • ⼤規模な導⼊をする際は切り替えを⾃動化する仕組 みがあれば⼈間が頑張らずうまくいくケースがある
  32. © - BASE, Inc. ご清聴 ありがとうございました