秒間1800リクエストの世界 / The world of 1800 reqs per sec

秒間1800リクエストの世界 / The world of 1800 reqs per sec

PHPカンファレンス福岡2017の資料です

40575ebf9c2f4a6e3bcb68630f446a3b?s=128

HASEGAWA Tomoki

June 10, 2017
Tweet

Transcript

  1. 3.

    ライフワーク: Web / iOSアプリ開発, ビール, 電子工作,
 サッカー観戦, レンタルカートレース, … 長谷川

    智希 Web / iOS App Development, Beer, IoT, Watch soccer match, Rental Kart Racing, … デジタルサーカス株式会社 副団長CTO Digital Circus, Inc. Vice-master CTO Tokyo, Japan Lifeworks: @tomzoh
  2. 4.
  3. 5.
  4. 6.

    WE ARE HIRING!! Web Development Mobile App Development ( )

    (iOS, Android) http://www.dgcircus.com Omotesando, Tokyo
  5. 11.

    システム構成 Ȑ Ȑ 2 × m4.large vCPU: 2 / memory:

    8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB iOS / Android Mobile Apps 1,000,000users
  6. 19.

    負荷 • 負荷がやってくる • 耐えられる様にしたい • 負荷を想定 • 耐えられそうな仮構成を作る •

    負荷を作り出して構成を調整 • どうやって耐えるか • Webサーバ(EC2)のスケールアウトで対応したい • DB(RDS)がツラければスケールアップする
  7. 20.

    • 耐えられる様にしたい • 負荷を想定 • 耐えられそうな仮構成を作る • 負荷を作り出して構成を調整 負荷 •

    負荷がやってくる • どうやって耐えるか • Webサーバ(EC2)のスケールアウトで対応したい • DB(RDS)がツラければスケールアップする
  8. 30.

    Ȑ

  9. 31.
  10. 35.

    PV → API • ユーザがどういう行動を取るか • シナリオを作成 • シナリオの各ステップで発生するAPIコールをリストアップ •

    シナリオの各ステップから、同じ動作をWebで実施した場合 に発生するPVに変換 • PV → APIコールの変換ができる
  11. 36.

    シナリオ No. 操作 ユーザ 操作 処理 時間 仮想 PV 1

    アプリ初回起動 1 2 ログイン画面からのログイン処理 10 1 2 3 ホーム表示 2 1 1 4 検索タブ表示 2 1 5 検索 10 2 3 6 検索結果一覧画面表示 1 7 (詳細画面 → エントリー)x 30 3,000 120 120
  12. 37.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375
  13. 38.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375 3,000PV/sec
  14. 39.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375 3,000PV/sec
  15. 40.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375 3,000PV/sec
  16. 41.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375 3,000PV/sec
  17. 42.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375 3,000PV/sec
  18. 43.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375
  19. 44.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375
  20. 45.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375
  21. 46.

    シナリオとその割合 シナリオ ユーザ 操作 処理 時間 仮想 PV 創出 PV/秒

    シナリオ 割合 必要 PV/秒 同時セッシ ョン シナリオ1 3,022 127 128 0.04 20% 600 14,761 シナリオ2 27 10 8 0.22 40% 1,200 5,550 シナリオ3 21 11 5 0.16 35% 1,050 6,720 シナリオ4 20 10 12 0.40 5% 150 375
  22. 48.

    • 耐えられる様にしたい • 負荷を想定 • 耐えられそうな仮構成を作る • 負荷を作り出して構成を調整 負荷 •

    負荷がやってくる • どうやって耐えるか • Webサーバ(EC2)のスケールアウトで対応したい • DB(RDS)がツラければスケールアップする
  23. 49.

    システム構成 Ȑ Ȑ 2 × m4.large vCPU: 2 / memory:

    8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB
  24. 50.

    システム構成 Ȑ Ȑ 2 × m4.large vCPU: 2 / memory:

    8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB Ȑ Ȑ 16 × m4.large vCPU: 2 / memory: 8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ
  25. 51.
  26. 53.

    Apacheをちゃんと設定する • Apacheのプロセス数をいくつにする? $ ps aux USER PID %CPU %MEM

    VSZ RSS TTY www-data 11270 0.0 0.3 441636 26720 ? STAT START TIME COMMAND S 06:25 0:02 /usr/sbin/apache2 -k start
  27. 54.

    Apacheをちゃんと設定する • Apacheのプロセス数をいくつにする? $ ps aux USER PID %CPU %MEM

    VSZ RSS TTY www-data 11270 0.0 0.3 441636 26720 ? STAT START TIME COMMAND S 06:25 0:02 /usr/sbin/apache2 -k start
  28. 55.

    Apacheをちゃんと設定する • Apacheのプロセス数をいくつにする? $ ps aux USER PID %CPU %MEM

    VSZ RSS TTY www-data 11270 0.0 0.3 441636 26720 ? STAT START TIME COMMAND S 06:25 0:02 /usr/sbin/apache2 -k start Ȑ m4.large vCPU: 2 / memory: 8GB
  29. 56.

    Apacheをちゃんと設定する • Apacheのプロセス数をいくつにする? $ ps aux USER PID %CPU %MEM

    VSZ RSS TTY www-data 11270 0.0 0.3 441636 26720 ? STAT START TIME COMMAND S 06:25 0:02 /usr/sbin/apache2 -k start Ȑ m4.large vCPU: 2 / memory: 8GB 8GB中1.6GB(20%)くらいOSに…。 残り80%(6.4GB)をApacheに。
  30. 57.

    Apacheをちゃんと設定する • Apacheのプロセス数をいくつにする? $ ps aux USER PID %CPU %MEM

    VSZ RSS TTY www-data 11270 0.0 0.3 441636 26720 ? STAT START TIME COMMAND S 06:25 0:02 /usr/sbin/apache2 -k start Ȑ m4.large vCPU: 2 / memory: 8GB 8GB中1.6GB(20%)くらいOSに…。 残り80%(6.4GB)をApacheに。 80% / 0.4% = 200
  31. 59.

    • 耐えられる様にしたい • 負荷を想定 • 耐えられそうな仮構成を作る • 負荷を作り出して構成を調整 負荷 •

    負荷がやってくる • どうやって耐えるか • Webサーバ(EC2)のスケールアウトで対応したい • DB(RDS)がツラければスケールアップする
  32. 61.
  33. 63.

    JMeterでシナリオを実装する シナリオ ウェイト 処理 時間 仮想 PV 創出 PV/sec シナリオ

    割合 必要 PV/秒 同時セッシ ョン シナリオ2 27 10 8 0.22 40% 1,200 5,550 
  34. 64.

    JMeterでシナリオを実装する シナリオ ウェイト 処理 時間 仮想 PV 創出 PV/sec シナリオ

    割合 必要 PV/秒 同時セッシ ョン シナリオ2 27 10 8 0.22 40% 1,200 5,550 
  35. 67.
  36. 70.
  37. 75.

    システム構成 Ȑ Ȑ 16 × m4.large vCPU: 2 / memory:

    8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ
  38. 76.

    システム構成 Ȑ Ȑ 16 × m4.large vCPU: 2 / memory:

    8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ 5 × m4.large vCPU: 2 / memory: 8GB EC2 Ȑ Ȑ Ȑ
  39. 77.
  40. 78.
  41. 79.
  42. 80.

    システム構成 Ȑ Ȑ 16 × m4.large vCPU: 2 / memory:

    8GB  EC2 RDS db.m3.xlarge vCPU: 4 / memory: 7.5GB Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ Ȑ 5 × m4.large vCPU: 2 / memory: 8GB EC2 Ȑ Ȑ Ȑ
  43. 82.

  44. 83.
  45. 99.
  46. 104.

    • Webサーバ、16 x m4.xlarge で大丈夫そう。 • 結局、4 x m4.4xlarge にした。

    • Apacheのプロセス数は2,116。 • 大丈夫 = Apacheがエラーを吐かない • エラーを吐くとELBからはずされてサービスダウン 負荷テストの結果
  47. 105.

    • Webサーバ、16 x m4.xlarge で大丈夫そう。 • 結局、4 x m4.4xlarge にした。

    • Apacheのプロセス数は2,116。 • 大丈夫 = Apacheがエラーを吐かない • エラーを吐くとELBからはずされてサービスダウン 負荷テストの結果
  48. 106.

    • Webサーバ、16 x m4.xlarge で大丈夫そう。 • 結局、4 x m4.4xlarge にした。

    • Apacheのプロセス数は2,116。 • 大丈夫 = Apacheがエラーを吐かない • エラーを吐くとELBからはずされてサービスダウン 負荷テストの結果
  49. 107.

    • Webサーバ、16 x m4.xlarge で大丈夫そう。 • 結局、4 x m4.4xlarge にした。

    • Apacheのプロセス数は2,116。 • 大丈夫 = Apacheがエラーを吐かない • エラーを吐くとELBからはずされてサービスダウン 負荷テストの結果
  50. 108.

    • Webサーバ、16 x m4.xlarge で大丈夫そう。 • 結局、4 x m4.4xlarge にした。

    • Apacheのプロセス数は2,116。 • 大丈夫 = Apacheがエラーを吐かない • エラーを吐くとELBからはずされてサービスダウン 負荷テストの結果 お得
  51. 109.

    • Webサーバ、16 x m4.xlarge で大丈夫そう。 • 結局、4 x m4.4xlarge にした。

    • Apacheのプロセス数は2,116。 • 大丈夫 = Apacheがエラーを吐かない • エラーを吐くとELBからはずされてサービスダウン 負荷テストの結果
  52. 127.
  53. 128.
  54. 131.

    2/28 9:00 JST 15:00 JST 21:00 JST 9:00 JST 3/1

    3:00 JST サイト・アプリオープン RDS
  55. 132.

    2/28 9:00 JST 15:00 JST 21:00 JST 9:00 JST 3/1

    3:00 JST サイト・アプリオープン 0:03JST 1,800リクエスト/秒 RDS
  56. 133.

    2/28 9:00 JST 15:00 JST 21:00 JST 9:00 JST 3/1

    3:00 JST サイト・アプリオープン 0:03JST 1,800リクエスト/秒 RDS
  57. 141.
  58. 145.

    mysql> explain select * from users where *****************************; +----+-------------+-------+------------+------+---------------+------+---------+- |

    id | select_type | table | partitions | type | possible_keys | key | key_len | +----+-------------+-------+------------+------+---------------+------+---------+- | 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | +----+-------------+-------+------------+------+---------------+------+---------+- 1 row in set, 1 warning (0.00 sec) mysql> select id from users where *****************************; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.25 sec)
  59. 146.

    mysql> explain select * from users where *****************************; +----+-------------+-------+------------+------+---------------+------+---------+- |

    id | select_type | table | partitions | type | possible_keys | key | key_len | +----+-------------+-------+------------+------+---------------+------+---------+- | 1 | SIMPLE | users | NULL | ALL | NULL | NULL | NULL | +----+-------------+-------+------------+------+---------------+------+---------+- 1 row in set, 1 warning (0.00 sec) mysql> select id from users where *****************************; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.25 sec) フルスキャンになってて0.25secかかってる…。 インデックス足してみよう。
  60. 147.

    mysql> explain select * from users where *****************************; +----+-------------+-------+------------+------+---------------+------------+---------+- |

    id | select_type | table | partitions | type | possible_keys | key | key_len | +----+-------------+-------+------------+------+---------------+------------+---------+- | 1 | SIMPLE | users | NULL | ref | index_hash | index_hash | 162 | +----+-------------+-------+------------+------+---------------+------------+---------+- 1 row in set, 1 warning (0.00 sec) mysql> select id from users where *****************************; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.00 sec)
  61. 148.

    mysql> explain select * from users where *****************************; +----+-------------+-------+------------+------+---------------+------------+---------+- |

    id | select_type | table | partitions | type | possible_keys | key | key_len | +----+-------------+-------+------------+------+---------------+------------+---------+- | 1 | SIMPLE | users | NULL | ref | index_hash | index_hash | 162 | +----+-------------+-------+------------+------+---------------+------------+---------+- 1 row in set, 1 warning (0.00 sec) mysql> select id from users where *****************************; +----+ | id | +----+ | 1 | +----+ 1 row in set (0.00 sec) 効果絶大やんけ…。
  62. 149.
  63. 152.
  64. 153.
  65. 154.

    本番に足したろ。 mysql> alter table users add index … 返ってこない…。 しかし

    Ctrl + C も怖い。 しばらく置いておこう…。 DBサーバの負荷がむっちゃ 下がったんですが、 何か起きてますか!?
  66. 155.

    RDS

  67. 159.
  68. 160.

    まとめ • 1,800リクエスト/秒の世界を体験した。 • 負荷試験 & 対策 • 負荷をかけるのにも工夫が必要。 •

    Apacheのエラーレートだけでなくサーバの
 リソース利用状況もチェックするべき。 • チューニング • Apacheで完結するアクセスは爆速。 • レコード数が多いテーブルではインデックス特に大事。
  69. 163.

    AWS / EC2の注意点 • いろいろなものに制限がある。 • EC2インスタンス数 • IPアドレス数 •

    どちらも申請すると上げてもらえるけど1〜2営業日必要 • 負荷テストをする時にも申請が必要 • これも1〜2営業日
  70. 164.
  71. 167.

    PHPerKaigi 2018 https://phperkaigi.jp スポンサー募集…するかも 2018.03.10(土) • PHPerのためのカンファレンス • 東京都練馬区 Coconeriホールにて

    • 朝から晩までテックトーク • 夕方からはビールを飲みながら • 夜はクラフトビールで懇親会