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

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

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide