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

スケールするというのはどういうことなのか

Kurochan
October 22, 2023

 スケールするというのはどういうことなのか

社内の勉強会で発表しました

Kurochan

October 22, 2023
Tweet

More Decks by Kurochan

Other Decks in Technology

Transcript

  1. スケールするというのはどういうことなのか
    株式会社サイバーエージェント AI事業本部

    黒崎 優太 (@kuro_m
    88
    )

    View full-size slide

  2. はなすこと
    • おもに⾮技術職向けに以下の解説をします


    • システムがスケールするっていうのはどういうことなのか


    • スケールさせるための基本的な考え⽅


    • 基本情報技術者試験で出そうなくらいの内容でやさしくしたつもり


    • キーワード


    • スケールアップとスケールアウト


    • アムダールの法則


    • リトライ


    • 冪等性

    View full-size slide

  3. [PR] イラスト図解でよくわかる ITインフラの基礎知識
    • 興味持ったらぜひ🤔


    • 書いたの5年前だけどそんなに変わってないはず
    https://gihyo.jp/book/
    8

    View full-size slide

  4. スケールアップと

    スケールアウト

    View full-size slide

  5. スケールするとは

    View full-size slide

  6. スケールする
    • ⽇本語だと「規模が⼤きくなる」?


    • システムの要求の規模が⼤きくなっても処理能⼒をそれに合わせて拡張でき
    ること


    • 情報科学の知識が役に⽴ちます

    View full-size slide

  7. スケールアップとスケールアウト

    View full-size slide

  8. スケールアップ
    1秒間に100リクエスト処理できるマシン
    100リクエスト/秒

    View full-size slide

  9. スケールアップ
    1秒間に100リクエスト処理できるマシン
    200リクエスト/秒
    処理不能

    View full-size slide

  10. スケールアップ
    1秒間に200リクエスト処理できるマシン
    200リクエスト/秒
    処理可能

    View full-size slide

  11. スケールアップ
    • 処理するリソースをより単体性能の⾼いものに置き換える


    • リソース = サーバ等


    • 1秒間に100リクエスト処理できるサーバを200リクエスト処理できるものに交換するなど


    • 交換するだけで性能向上が⾒込めるので簡単


    • スケールアップはわりとすぐに限界が来る


    • そんなに都合のいいマシンは世の中に存在しないから


    • CPU
    4
    コアのマシンを96コアのマシンにすることはできても、1024コアのマシンは⾮現実的


    • (あったとしても現代においては⾮常に⾼額でコスパが悪すぎる)


    • そのサーバが故障したときの影響がデカくなる(リスク集中)

    View full-size slide

  12. スケールアウト
    1秒間に100リクエスト処理できるマシン
    100リクエスト/秒

    View full-size slide

  13. スケールアウト
    1秒間に100リクエスト処理できるマシン x
    3
    300リクエスト/秒

    View full-size slide

  14. スケールアウト
    • 処理するリソースの単体性能は変えずに数を増やす


    • サーバを増やせば性能向上が⾒込めるので、スケールさせやすい


    • 安価なサーバを⼤量に買って並べるなど


    • スケールアップと組み合わせるのもOK


    • スケールアウトできるものであることが前提


    • サーバ1台でしか処理できないソフトウェアの場合、サーバを増やしてもスケールしない

    View full-size slide

  15. 例: ⼯場
    • 製品を1個つくるのに100単位時間かかる場合


    • 2並列で100単位時間かけると2個完成する


    • 4並列だと?
    100単位時間
    100単位時間

    View full-size slide

  16. 例: ⼯場
    • 製品を1個つくるのに100単位時間かかる場合


    • 4並列で100単位時間かけると4個完成する


    • スケールしている!
    100単位時間

    View full-size slide

  17. 例: ⼯場
    • 並列数の数だけスケールするということ


    • 4並列で100単位時間かけると4個完成する


    • スケールしている!


    • 100並列にすれば100個完成するということ
    単位時間あたりの⽣産量
    並列度

    View full-size slide

  18. アムダールの法則

    View full-size slide

  19. 並列度を上げればあげるほど処理能⼒は拡張されるのか?
    • 理論上はそう


    • 現実は…?


    • ⼈間界でもそんなうまい話はないはず
    https://www.maruzen-publishing.co.jp/item/?book_no=
    3

    View full-size slide

  20. 例: ⼯場
    • 製品を1個つくるのに100単位時間かかる場合


    • 95単位時間は並列化可能、5単位時間だけ並列化不可能


    • 2並列だと…?


    • 100単位時間あたりに1.95個完成する (ちょっと効率落ちた)
    50単位時間
    50単位時間
    5単位時間
    45単位時間
    45単位時間

    View full-size slide

  21. アムダールの法則
    • アムダールの法則


    • N = 並列度


    • P = 並列化できる割合


    • S(N) = 性能向上率


    • 製品を1個つくるのに100単位時間かかり、95%が並列化可能な場合


    • 2並列だと1.95個


    • 4並列だと3.47個


    • 10並列だと6.89個


    • 1,000並列だと19.62個


    • 10,000並列だと19.96個


    • 100,000並列だと19.99個 (全然効率上がってない…!🥺)

    View full-size slide

  22. アムダールの法則
    • アムダールの法則


    • N = 並列度


    • P = 並列化できる割合


    • S(N) = 性能向上率


    • 並列化不能な部分がある場合は⾼速化に

    限度がある!


    • 横軸の数字が⼤きくなっても縦軸の数字が

    途中からほぼ伸びなくなることに注⽬🥺


    • Nが極限になる(めちゃくちゃ並列数上げる)と


    • S =
    1
    / (
    1
    - P) で性能が頭打ちになる


    • ⼈間の仕事も⼀緒!

    View full-size slide

  23. スケールさせるには
    • できる限り並列化不可能な部分をなくす


    • Shared Nothing vs Shared Everything

    View full-size slide

  24. 失敗を許容する

    View full-size slide

  25. 失敗が許容できないシステム
    • 絶対にリクエストの失敗が許されないシステムを考えてみる


    • ユーザがN⼈いてそれぞれ1リクエストする場合


    • N =
    100
    :
    1
    0 0
    回に1回の失敗が許されない


    • N =
    1
    ,
    000
    :
    1
    ,
    00 0
    回に1回の失敗が許されない


    • N =
    10
    ,
    000
    : 10,000回に1回の失敗が許されない🔥


    • 失敗を許容しない場合、ユーザ数が増えるほどシステムの要件が厳しくなる


    • 無理


    • たまに失敗するのは諦めるしかないのか…?🤔

    View full-size slide

  26. 失敗を許容する = 諦める?
    • 例: 100回に1回エラーが発⽣するサーバ


    • エラーの発⽣確率 = 1%


    • クライアントが1回リトライしてもエラーになる確率 = 1% x
    1
    % =
    0
    .
    01
    %


    • クライアントが2回リトライしてもエラーになる確率 = 1% x
    1
    % x
    1
    % =
    0
    .
    0 001
    %


    • エラーが確率的に発⽣する場合、リトライすれば成功しそう!


    • 必ずしも 失敗を許容する = 諦める ということではない


    • もちろんエラー率99%とかだとリトライしてもあまり意味がない
    失敗
    リトライ
    成功

    View full-size slide

  27. リトライ / 冪等性

    View full-size slide

  28. 何も考えずにリトライすると…
    • とあるクライアント


    • サーバがエラーレスポンスを返したのですぐにリトライしました


    • またエラーだったのでリトライを10回繰り返しました


    • サーバが障害によりレスポンス不能だった場合に、

    クライアントが100台居た場合に何が起きるか


    • 10回リトライ x
    1 00
    台 = 1000リクエスト


    • サーバが障害になるとトラフィックが1,000倍になる🔥


    • 回復不能!負のループ!

    View full-size slide

  29. バックオフ
    • 何も考えずに即時リトライすることの危険性を回避する⼿法


    • ⼀定期間待ってからリトライする


    • バックオフ


    • 「⼀定期間」を指数関数的に伸ばしていくことが⼀般的(Exponential Backo
    ff
    )


    • サーバ障害発⽣時のクライアントの例:


    • 失敗→2秒後にリトライ→4秒後→8秒後、16秒後、32秒後、64秒後、128秒後…


    • 即座にリトライしてもダメだった場合、リトライの量が爆発しないように

    待機時間を伸ばしていくことでサーバを守る

    View full-size slide

  30. ジッター
    • 同じタイミングにクライアントからのアクセスが集中すると困る


    • リトライ時に間隔をあけても多数のクライアントのアクセス周期が集中すると
    困る


    • リトライにゆらぎ(ジッター, Jitter)を与える


    • 例: リクエスト失敗→2秒+0〜3秒後にリトライ→4秒+0〜3秒後、8秒+0〜3秒後…


    • 徐々に周期がズレていくはず


    • リトライ以外でもジッターは有効


    • Push通知の送信タイミングにジッターを加えることでアクセスのスパイクを緩和するなど

    View full-size slide

  31. 何も考えずにリトライすると…(その2)
    • 決済が2回実⾏された!


    • 商品が10個発送された!


    • ⾝に覚えのない履歴が追加された!


    • 何かしら事故りそうな予感👼

    View full-size slide

  32. 事故って困るケースってなんだろう
    • 決済履歴の取得に失敗したのでリトライしたら成功した => 困らない


    • 決済中に通信エラーになったのでリトライしたら2重に決済された => 困る!


    • 違いは「冪等性(べきとうせい)」があるかどうか


    • 何回やっても同じ結果になるかどうか

    View full-size slide

  33. 冪等でない処理を冪等にする技術
    • 冪等にするための⼿法の⼀例


    • 決済:


    • 🙅 危険な例: 100円の決済が成功したかわからないのでリトライした


    • 🙆 安全な例: 100円の決済(ID=abc)が成功したかわからないのでリトライした


    • 決済にIDが付与されていると、同じリクエストが来たかどうか判別可能


    • サーバは同じリクエストが2回来たことを検知したら「すでに受け付けました」というレ
    スポンスを返却して処理をスキップすればいい


    • クライアントは成功した確証が得られなければリトライすればいい

    View full-size slide

  34. その他のスケールさせるためのしくみ

    View full-size slide

  35. ⾮同期処理
    • 必ずその場で処理する必要がないものは「あとまわし」にする


    • ⼈間の例:


    • 受け付け番号を発⾏して、処理が完了したら呼び出す


    • サーバの例:


    • クライアントからのリクエストを即座に処理せず、キューに⼊れて処理IDのみ発⾏する


    • 定期的に進捗を問い合わせて、完了してたら結果が得られる(ポーリング)
    処理して
    あとでね(ID=
    1
    23
    )
    あとでやる
    キュー
    キューから取り出す

    View full-size slide

  36. 結果整合性
    • 結果整合性(Eventual Consistency)という概念もある


    • システムを分散(スケールアウト)させつつ整合性を取ることができる技術


    • 今回は扱いません、⼤規模にスケールするシステムではこの概念が出てくることが多い


    • 例: Con
    fl
    ict-free Replicated Data Type
    https://speakerdeck.com/kurochan/scala-with-cats-case-study-crdts

    View full-size slide

  37. まとめ
    • システムがスケールするというのはどういうことなのか


    • スケールアップとスケールアウトの違い


    • アムダールの法則により単に並列度を⾼めても限界があること


    • 絶対に失敗しないことよりも最終的に失敗しないことをとる⽅が合理的である

    (ことが多い)


    • 処理が冪等であればリトライが容易であること

    View full-size slide