tom__bo’s Blog

情報系学生が筋トレしたり、筋トレしたり筋トレしたことを書くブログ。もはやダイアリー

Systems Performance 読んでいく (2章 その3)

Systems Performance: Enterprise and Cloudを読んでいく。

前回に引き続き自分用メモ 2章は長かったので、3つに分けました。2章最後で、6節から2章最後まで。

2.6 Modeling

分析的なモデリングは様々な方法で行われるが、特に"scalability analysis"(スケーラビリティの分析)のために行われることが多いだろう
分析的なモデリングはパフォーマンス評価を行う上での3つ目に分類でき、モデリングの他に残る2つは、対象を観察する"measurement"と、実験的にテストを行う"simulation"である。 パフォーマンスに関してよく理解できたといえるのは、分析的なモデリング+シミュレーション、もしくはシミュレーションと計測のように、3のうち2つが達成できた時である。

Scalability analysisは、スケールした時にどの時点で線形にパフォーマンスが改善するのが終わり、"knee point"を迎えるのかを明らかにする。

2.6.2 Visual Identification

スケーラビリティに関する十分なデータが取れたらそれをプロットしよう。 得られたパフォーマンスとスケーラビリティの関係が明らかになるはずである。

図2.15ではスレッドの数が増えるにしたがってアプリケーションのスループットが上がっている様子がわかる。

図2.15 f:id:tom__bo:20161214155044p:plain

図2.16では外形の呼び方が紹介されている

図2.16 f:id:tom__bo:20161214155054p:plain

  • Linear: 比例
  • Contention: 競合(?)
  • Coherence: 一貫性 (一貫性を保つために性能が悪くなり始める)
  • Knee Point: ニーポイント
  • Ceiling: 頭打ち、最高限度

視覚的に現象を理解することは簡単だが、我々は数学的なモデルとしてもこれらを理解する必要がある。
この後の節でAmdahl's Law of Scalability, Universal Scalability Law, queueing theoryについて紹介する

2.6.3 Amdahl's Law of Scalability

  • Gene Amdahlにちなんでアムダールの法則と名付けられた
  • CPUやスレッド、負荷は並行にスケールしないという法則
  • 前の節の"Contention"で表現される形になる

CPUの数などの、スケールさせる物の次元をN, 相対的なキャパシティをC(N)とすると、"the degree of seriality"(並列化できる部分の割合?)を表すα(0 <= α <= 1)というパラメータが存在する。
そして、αにしたがってLinearな状態から下方にそれた結果となる

C(N) = N/1 + α(N-1)

このアムダールの法則の部分の訳はかなり自信がない。

よく見る形式の参考にwikipediaの例を載せておくと、
性能向上率をS(N), 並列化可能な部分をPとし、スケールさせるもの(CPUなど)の数をNとした時


\begin{equation}
S(N) = 1 /  (1 - P) + \frac{P}{N}
\end{equation}

と書ける。
結局変形すると同じ式になった。


2.6.4 Universal Scalability Law

  • Dr. Neil Guntherによって紹介された
  • Amdahlの法則に一貫性による競合を取り入れたもの

Amdahlの法則の変数に一貫性のパフらメータβを取り入れる(β==0の時アムダールと同じ)

C(N) = N/1 + α(N - 1) + βN(N - 1)

2.6.5 Queueing Theory

Queueing Theory(待ち行列理論)は待ち行列の長さ、待ち時間(レイテンシ)、時間ベースの利用率を分析するための数学的な理論。
ソフトウェアやハードウェアは"queueing systems"と捉えることができ、これらが複数あるものは"queueing networks"と言える。

この節では待ち行列理論の役割を理解するために、まとめと例を挙げる。待ち行列理論は広大な領域なので、別途学習する必要がある

待ち行列理論は数学と統計の領域に成り立っており、特に以下のようなものも含む

  • probability distributions
  • stochastic processes
  • Erlang's C formula
  • Little's Law

Little's Lawは以下の式で表される

L = λW

これはあるシステムにおけるリクエストの平均, Lが、平均到着率,λと、平均サービス時間,Wによって定義されることを示している

待ち行列理論は以下のような様々な疑問に回答することができる

  • 負荷が2倍になった時に平均応答時間がどう変化するか?
  • プロセッサを追加した時に平均応答時間にどのような影響を与えるか?
  • 負荷が2倍になった時に、90%の応答を10ms以内に返せるか?

平均応答時間から離れて、利用率やqueueの長さ、残存するタスクの数などもについても研究されている 単純なqueueのシステムモデルを図2.18に示す。

このキューイングシステムは以下の3つの要因にカテゴライズされる

  • Arrival process
    • キューにリクエストが到着する間隔
    • この間隔はランダムだったり固定だったり、ポアソン分布に従うものだったりする
  • Service time distribution
    • サービス時間を表す
    • これも固定だったり、特定の字数分布だったりする
  • Number of service centers
    • 1つだったり複数だったりする

これらは"Kendall's Notation"によって表現される

A/S/m

それぞれが上の要素に対応する。
また、これにバッファを加えた拡張バージョンもある。
一般的によく学習されているのは以下である。

  • M/M/1
    • Markovian arrivals(exponentially distributed arrival time)
    • Markovian service times (exponentially distribution)
    • one service center
  • M/M/c
    • M/M/1のマルチサーバ
  • M/G/1
    • M/M/1のgeneral distribution(何でも良い)
  • M/D/c
    • M/M/1のdeterministic service time(固定)

rotational hard disk環境のパフォーマンスとしては一般にM/G/1が使われる。
例えば、単純化のためにディスクが一定の時間でレスポンスを返すとしたモデルはM/D/1である。

ここで生じる疑問は、レスポンス時間は利用率に応じてどのように変化するのかというものである。
待ち行列理論はM/D/1に対して応答時間の計算を可能にしてくれる

r = s(2-ρ) / 2(1-ρ)

応答時間, rは、サービス時間sと、利用率, ρによって上のように定義される

サービス時間が1ms, 利用率が0~100%の時の応答時間を図2.19に示す

60%を超えたあたりから、平均応答時間は2倍になり、80%で3倍になっていることがわかる。

実際のdiskやCPUでは優先度によりタスクが先に処理されたりするので、この図とは違う分布になる。
しかし、使用率が高くなることの影響がかなり大きいことが直感的に理解できるだろう。

2.7 Capacity Planning

Capacity Planningはシステムが負荷にどの程度対応し、負荷に対してスケールできるかを調べるものだ。
それにはいくつかの方法があるが、この節ではロードバランサ、シャーディングを含む解決法を紹介する。

このトピックについて詳しく知りたければ、"The Art of Capacity Planning"を読むと良い。

2.7.1 Resource Limits

この方法では負荷がかかった状態でのボトルネックとなるリソースを探す。

  • サーバのリクエストの割合を計測する、そして継続的に監視する
  • ハード・ソフトの利用率を調べる、この割合も継続的に監視する
  • リソースの利用率を発生させているリクエストを絞り出す
  • それぞれのリソースに対してリクエストの制限を絞り出す

まず、サーバの役割とそれが受けるリクエストの性質を特定する。webサーバならhttpリクエスト、DBならSQLクエリというように。
次に、リクエストごとにシステムのリソースをどの程度消費しているかを決定する。現在動作しているサーバであれば、リクエストに対する利用率の割合が計測できる。
将来のシステムのために、ベンチマークツールや負荷発生ツールを利用することもできる。
これにより、実験的にリソースの制限を計測することができる。

例えば、1000requests/sのシステムを考える。
今一番忙しいのは利用率が40%の16個のCPUである。
これが利用率100%になる時、秒間何リクエストを処理しているだろうか?
(計算式は省略) リクエストあたりのCPU利用率は0.64%なので、100%になるのは2500req/sである。
しかしこれは概算で、最善のケースでの話である。
実際には他の要因が絡んで、この値にはならないだろう

この計算はアプリケーションのスループットのデータのみを使った単純なものである。
実際に常にサーバの状態を監視することができたら、より正確な予測ができるだろう。

これで2500req/sとわかったがこれで十分だろうか?もし100000hits/dayのwebサイトがあったとしよう、
すると平均では1req/sにもならないが、これが新しい投稿があったあとに100000hitsするのであればその負荷は甚大なものになる。

2.7.2 Factor Analysis

新しいハードウェアを購入して、システムをデプロイするときには内部でパフォーマンスに関わる様々なものが変わっている。
CPUのRAMの量もRAIDの設定もファイルシステムの設定も変わっているだろう。個々でのしごとはたいてい求めるパフォーマンスを低価格で実現することだろう。

システムの全ての要因のパターンをテストしてみることは不可能なので、最大限のシステムの理解を元にテストを行う必要がある。

  • 全ての要因を最大限の性能にする
  • ひとつずつ性能を下げてパフォーマンスをテストする
  • 測定結果を元にそれぞれのパフォーマンスの落ち具合を計測する
  • 求められる秒間のリクエストと、組み合わせによるパフォーマンスの落ち具合をメンテナンスしつつ、最大限の性能から初めて、コストカットできる項目を選択していく
  • 確認のために求められた性能で再度パフォーマンステストを行う

2.7.3 Scaling Solutions

高いパフォーマンスに求められるのはしばしば大きいシステム(larger system)であり、これを"vertical scaling"という。"load balancers"というシステムを手前におき、負荷を複数のサーバに分散することを"horizontal scaling"という。

Coud computingではよりhorizontal scalingの手法が取られる。
これは仮想化された小さいシステムによって成り立っているためで、必要な分に応じてシステムを用意できる。
なので、エンタープライズの厳格な契約をしたり、厳密なスケール計画を立てる必要も少なくなってきた。

DBにおけるスケール戦略は"sharding"である。
この方法ではデータを論理的な部分に分けて別のサーバで管理するのである。
スケーラビリティの戦略はあなたが利用したいシステムの負荷に依存するので、より詳しく知りたければScalable Internet Architecturesを読むといいだろう。

2.8 Statistics

統計を利用し、その限界を理解することは重要だ。この説では統計をパフォーマンスにどのように利用するかを、平均・標準偏差・百分率を含めて紹介する。

2.8.1 Quantifying Performance

パフォーマンスの問題を定量化することはそれらを比較可能にしたり、優先権を与えたりできるようにする。
これらは観察と実験によってなされる。

  • 観察ベース
    • 信頼できるメトリクスを選択する
    • 問題を解決するために必要なパフォーマンスを見積もる
    • アプリケーションのリクエストが10msかかっていると観察する
    • そのうち9msがディスクI/Oと観察する
    • DRAMにキャッシュできればレイテンシは10μs以下にできると期待して設定する
    • 期待する効果は1.01msなので、もとの10msより9倍早くなると見積もる

このような方法は2.3章で説明したレイテンシの方法がよく利用できる。
この時、レイテンシを利用するということはその処理の中に非同期な部分が含まれているかもしれないことに注意する。
非同期でディスクI/Oが走っていると、アプリケーションの性能にはそれほど影響していないかもしれない。

  • 見積もりベース
    • 修正を適用する
    • 変更前と後で結果を比較する
    • トランザクションのレイテンシが平均10msと観察する
    • 並行性を挙げるためにアプリケーションのスレッド数を上げる
    • トランザクションのレイテンシが平均2msになる
    • 5倍早くすることが出来た

この方法は本番の環境で試すにはコストが掛かり過ぎる

2.8.2 Averages

平均は一つの値の中心的な傾向を表現する値である。その最も一般的な平均は"arithmetic mean(単にmeanとも)":算術平均である。これは単に値の合計をその数で割ったものである。
この他に"geometric mean", "harmonic mean"などがある。

  • Geometric Mean
    • 幾何平均
    • n次のrootをとったもの
    • ネットワークの分析などでも使われる
    • 最終的に同じデータを転送するが、独立して計測したカーネルのネットワークスタックの改善結果があったとき、その平均がどうなるか
    • こういった場合、改善は掛け算的に効いて来るので、幾何平均を使う
  • Harmonic Mean
    • 調和平均
    • 要素の合計をその相互作用ごとに平均する
    • 800MBを転送するとき、最初の100MBは50MB/s, 残りの700MBは10MB/sで転送できるとする
    • この調和平均は800/(100/50 + 700/10)=11.1となる
  • Averages over Time
    • パフォーマンスにおいては時間に対する平均を取ることも多い
    • cpuの使用率50%はある一定期間の50%の期間CPUが使われたということである
    • この期間は秒、分、時間でもとりうる
    • 例えばあるシステムがサチュレーションを起こしていて、顧客の提示するCPU使用率が80%ということだったが、それは5分間の平均の値だったということがある。これは細かい単位で100%に達していることがあるということだ
  • Decayed Average
    • Decayed Averageはシステムパフォーマンスにおいて時々使われる。
    • 例えばuptimeによって報告される"load averages"がそうだ
    • これは継続して一定の期間ごとに算出される値で、一番最近の物により価値がある
    • これは計測期間より短い期間での変動を見れないので注意する
    • "Load Average"に関しては6.6 Analysisで扱う

2.8.3 Standard Deviations, Percentiles, Median

図2.21がわかりやすい

図2.21 f:id:tom__bo:20161214155123p:plain

2.8.4 Cofficient of variation

  • 変動係数
  • CovまたはCVと表される

2.8.5 Multimodal Distributions

  • 実際の分散を考えるとディスクレイテンシは通常は遅いが、一部はキャッシュにのって早いなど、多項分布になる
  • 図2.22のようにヒストグラムにすると最貧値(ピーク)が2つあることがわかる
  • 平均だけを見るとこういった傾向を見逃すことがあるので、注意する

図2.22 f:id:tom__bo:20161214155133p:plain

2.8.6 Outliers

  • 外れ値の存在を無視できない
  • これらは平均をずらすが、中央値ではそれほど影響しない
  • 99パーセンタイルを使うことで外れ値を見つけやすくなるが、頻度による
  • 外れ値や多項分布を完全に見抜くには、ヒストグラムのような完全な分布を見るのが良い

2.9 Monitoring

パフォーマンスの監視は時系列に行われる。過去のデータを現在のものと比較できることは非常に有用だ。
これは量的な増加やピーク時の使用率が簡単にわかり、キャパシティプランニングに利用できる。

2.9.1 Time-Based Patterns

図2.23~ 図2.25が示すように時間ごと、日毎、週ごと、1/4年単位で見ることで傾向がひと目でわかる

図2.23 ~ 2.25 f:id:tom__bo:20161214155145p:plain

2.9.2 Monitoring Products

世間には様々なサードパーティ製のシステムパフォーマンスモニタリングツールがある。
特にこれらはアーカイブしたデータを読み込み、webブラウザから見られるようにしたものが多い。
これらのいくつかはシステム上で"agent"をはしらせ、このエージェントがメトリクスを取得し、外部に送ったり、直接ブラウザに情報を提供したりする。

また、SNMPを使ったモニタリングすることもある。
たいていSNMPは標準であるので、外部のサービスを使う必要はない

2.9.3 Summary-since-Boot

もしモニタリングがうまく動作していないようであれば、少なくともOSが提供してくれる"summary-since-boot"の値を活用しよう

2.10 Visualizations

  • 2.10.1 Line Chart
  • 2.10.2 Scatter Plots
  • 2.10.3 Heat Maps
  • 2.10.4 Surface Plot