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

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

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

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

Satoshi Kawashima

June 04, 2020
Tweet

More Decks by Satoshi Kawashima

Other Decks in Technology

Transcript

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

    マスター/リードレプリカ構成のRDBMSに対して負 荷分散の⽬的でアプリケーションのアクセス先を制 御する • 参照系クエリをリードレプリカに寄せることでマス ターのマシンリソースを有効活⽤できるようになる
  2. © - BASE, Inc. BASEの背景 • サービスの成⻑によってトラフィックの量が増⼤していた • ⼈気ショップのセールによる瞬間的な⾼負荷が発⽣すること もあった

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

    リード専⽤ModelやBehaviorによって部分的に実現 していたが、もっと汎⽤的なR/W Splittingライブラ リが必要になってきたので作ることになった • ※コネヒトさんがCakePHP のR/W Splittingライブラリを公開する以前なの で⾃作するしかなかった
  4. © - BASE, Inc. ユースケース3:アプリケーション単位で適⽤ • アプリケーション単位で全てのDBアクセスをデフォ ルトではリードレプリカへ向けてしまうドラス ティックな適⽤ •

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

    後の改修の影響を受けやすいリスクが有る 最初は参照クエリだけだったが、 後の改修で更新クエリが 発⾏されるようになる可能性がある
  6. © - BASE, Inc. 部分適⽤ではコネクション数は減らない 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ

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

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

    参照クエリ 参照クエリ ͱ͋ΔࢀরΫΤϦ͔͠ൃߦ͠ͳ͍ ίϯτϩʔϥΞΫγϣϯ͕ݺ͹Εͨ࣌ リードレプリカ ※理想的な状態はこっち、DBコネクションは1つ
  9. © - BASE, Inc. 安全装置の実装 Model Switchable Datasource Behavior Switchable

    Mysql (DataSource) SwitchablePDO PDO PDO Master ReadReplica ReadReplica ModelίʔϧόοΫʹΑͬͯ ॻ͖ࠐΈɾ࡟আΛݕ஌ (beforeSave/beforeDelete) τϥϯβΫγϣϯ։࢝Λݕ஌ ߋ৽ܥΫΤϦΛ ਖ਼نදݱͰݕ஌
  10. © - BASE, Inc. ⼀度だけコネクション数が減らしたいタイミングがあった • マスターのコネクションキャパシティの上限が近づ いてコネクション数を減らす必要が出てきた • アプリケーション単位での切り替え(デフォルトで

    リードレプリカに向けて、更新系クエリが投げられ る箇所を明⽰的にマスターへ向ける)を実⾏した • ほとんど参照しか無いと分かっているアプリケー ションだったので⼤丈夫だと判断された
  11. © - BASE, Inc. ⼤規模切り替えの結果 • うまくいった ϦϦʔεલ͸ Ϛελʔ:ϦʔυϨϓϦΧͷ ίωΫγϣϯ਺͸

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

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

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

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