Slide 1

Slide 1 text

© - BASE, Inc. 2020/06/04 コネヒトマルシェ オンライン 川島 慧/@nazonohito 既存サービスに後から R/W Splittingライブラリを⼊れる時に考えたこと

Slide 2

Slide 2 text

© - BASE, Inc. Product Division 川島 慧 @nazonohito

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

© - BASE, Inc. 背景について

Slide 7

Slide 7 text

© - BASE, Inc. BASEの背景 • サービスの成⻑によってトラフィックの量が増⼤していた • ⼈気ショップのセールによる瞬間的な⾼負荷が発⽣すること もあった BASEが今後も安定して成⻑していくために データベースのスケーラビリティが ⼤きな課題になってきた

Slide 8

Slide 8 text

© - BASE, Inc. それまでのR/W Splitting事情 • CakePHP 公式で⽤意されている仕組みはない • リード専⽤ModelやBehaviorによって部分的に実現 していたが、もっと汎⽤的なR/W Splittingライブラ リが必要になってきたので作ることになった • ※コネヒトさんがCakePHP のR/W Splittingライブラリを公開する以前なの で⾃作するしかなかった

Slide 9

Slide 9 text

© - BASE, Inc. 実装⽅針を考える

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

© - BASE, Inc. ユースケースを想定して設計する • 既存コードに対するR/W Splittingの適⽤⽅法をある 程度類型化して考えを整理する

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

© - BASE, Inc. ユースケース1:スロークエリを狙い撃ちした部分適⽤ • NewRelicなどのアプリケーション監視からボトル ネックとなっているクエリを発⾒して、それだけを リードレプリカに向ける • クエリの実⾏負荷は特定のクエリに偏在しているの で、最も費⽤対効果の⾼い適⽤⽅法

Slide 14

Slide 14 text

© - BASE, Inc. ユースケース2:コントローラアクション単位で適⽤ • コントローラアクション単位でリードレプリカに向 ける • 参照系コントローラアクションなど、参照クエリし か無いと分かっている箇所にまとめてリードレプリ カに向ける

Slide 15

Slide 15 text

© - BASE, Inc. ユースケース3:アプリケーション単位で適⽤ • アプリケーション単位で全てのDBアクセスをデフォ ルトではリードレプリカへ向けてしまうドラス ティックな適⽤ • 更新系クエリ全てに対して明⽰的にマスターへ向け てやる必要がある • 最も負荷分散の効果が⾼いが、更新系クエリの⾒逃 しやレプリケーション遅延による影響が危惧される

Slide 16

Slide 16 text

© - BASE, Inc. 3つの想定ユースケース • 後者のユースケースほど適⽤範囲が広くて適⽤が⼤変 • 初期導⼊時に広範囲のコードを読む必要がある • 後の改修の影響を受けやすいリスクが有る 最初は参照クエリだけだったが、 後の改修で更新クエリが 発⾏されるようになる可能性がある

Slide 17

Slide 17 text

© - BASE, Inc. 考えたこと • 基本的にはスロークエリを狙い撃ちするアプローチ になると思う • ただDBコネクション数を減らす効果は薄いので、広 い範囲への適⽤はいずれ避けられないと考えていた

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

© - BASE, Inc. 部分適⽤ではコネクション数は減らない 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ 参照クエリ ͱ͋ΔࢀরΫΤϦ͔͠ൃߦ͠ͳ͍ ίϯτϩʔϥΞΫγϣϯ͕ݺ͹Εͨ࣌ リードレプリカ ※理想的な状態はこっち、DBコネクションは1つ

Slide 21

Slide 21 text

© - BASE, Inc. 安全装置の実装 • リードレプリカに発⾏してほしくないクエリが実⾏ されかけた場合に、ライブラリ側で検知して⾃動で マスターへ切り替える仕組み • リードレプリカに発⾏されてほしくないもの • 更新系クエリ • トランザクション • etc

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

© - BASE, Inc. R/W Splittingの適⽤

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

© - BASE, Inc. ⼀度だけコネクション数が減らしたいタイミングがあった • マスターのコネクションキャパシティの上限が近づ いてコネクション数を減らす必要が出てきた • アプリケーション単位での切り替え(デフォルトで リードレプリカに向けて、更新系クエリが投げられ る箇所を明⽰的にマスターへ向ける)を実⾏した • ほとんど参照しか無いと分かっているアプリケー ションだったので⼤丈夫だと判断された

Slide 26

Slide 26 text

© - BASE, Inc. ドラスティックな切り替えの⽅法 • コードを全部調べ上げてやるのは量的に厳しい • ⾃動テストや⼿動テストで動作確認しつつ、漏れた 部分は安全装置による⾃動切り替えに頼って切り替 えを実⾏した

Slide 27

Slide 27 text

© - BASE, Inc. ⼤規模切り替えの結果

Slide 28

Slide 28 text

© - BASE, Inc. ⼤規模切り替えの結果 • うまくいった ϦϦʔεલ͸ Ϛελʔ:ϦʔυϨϓϦΧͷ ίωΫγϣϯ਺͸ ͓͓Αͦ3:1 ϦϦʔεޙ͸΄΅1:1΁ ϚελʔͷίωΫγϣϯ਺͸ 1/2ۙ͘·ͰԼ͕Γɺ ٯʹϦʔυϨϓϦΧ͸2ഒʹͳͬͨ

Slide 29

Slide 29 text

© - BASE, Inc. ⼤規模切り替えの結果 • サービス影響は出さずにコネクションを⼤幅に減ら せた • 参照クエリの殆どがリードレプリカに向いたのでマ スターの負荷も下がった • ただし、その裏側では安全装置が凄まじい回数起動 していた • 安全装置によってサービス影響が抑えられていた

Slide 30

Slide 30 text

© - BASE, Inc. 考察 • ドラスティックな切り替えでも安全装置があれば案 外なんとかなってしまった • ⼈間が頑張らない機械的なアプローチでもいくつか 条件が重なればこういうアプローチもありうること が分かった ※レプリケーション遅延による更新の反映されていない参照が発⽣するリスクは潜在的にあるが、 Auroraはレプリケーション遅延が発⽣しづらいらしいのでそこで抑えられているのかもしれない

Slide 31

Slide 31 text

© - BASE, Inc. まとめ • 既存のコードベースに後からR/W Splittingを導⼊し ていく際に考えたことを共有 • 基本的にはスロークエリを狙い撃ちした部分適⽤で 良さそうだが、コネクション数の削減を⽬指すと⼤ 規模な導⼊は避けられない • ⼤規模な導⼊をする際は切り替えを⾃動化する仕組 みがあれば⼈間が頑張らずうまくいくケースがある

Slide 32

Slide 32 text

© - BASE, Inc. ご清聴 ありがとうございました