Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
高負荷に耐えうる
WebApplication Server
の作り方
GMOインターネット株式会社
次世代システム研究室
石山 雄太
1/71
Xin chào!
Toi ten la Ishiyama Yuta.
GMO Internet inc.
次世代システム研究室
(Innovation and Technology System Office)
アシスタントマネージャー(As...
Goal
高負荷に耐えうる WebApplication の Architecture
を設計する際に
・どこで対策するか
・どのように作るか
をご紹介します。
Programing codeではなくinfraよりの説明になり
ます。高負荷対策...
section 0
対象とするWebApplicationの説明(前提)
section 1
どういった案があるか説明(抽象的)
section 2
設定の説明(具体的)
pages 71.
Agenda
4
Section 0
対象とするWebApplicationの説明(前提)
5
PJ code「C2」
スマートフォン向けゲームのサーバーにて行った負荷
対策を元に説明します
・[OS] CentOS7
・[WEBサーバー] NGINX
・[APIサーバー] NGINX + PHP-FPM
・[CACHE] Memcach...
全体構成図
7
LB
API
CACHE
memcached
DB
WEB・・・
master
・・
CACHE
Redis
slave
s/m
slave backup
s/m
slave backup
s/m
slave backup
s/...
全体構成図 ~改善ポイント~
8
LB
API
CACHE
memcached
DB
WEB・・・
master
・・
CACHE
Redis
slave
s/m
slave backup
s/m
slave backup
s/m
slave ...
Section 1
どういった案があるか説明(抽象的)
9
◆ scaleup (1台の性能を上げる)
性能が高いサーバーハードウエアを利用して性
能を上げる
◆ scaleout(台数を増やす)
サーバーを増やして合計の処理性能を上げる
◆ 他
programing codeの最適化
OS / Mid...
WEBサーバー
scaleup
scaleout
キャッシュ付きreverse proxy
CDN
11
「高性能サーバーを利用する」
静的HTMLや画像や動画ファイルなどContentsを配信するWEBサ
ーバーにおいて、scaleup時に重要視するのは、
CPU clock/core数です
Memoryはswapしない程度にあれば大丈夫です
C...
「サーバーを複数台用意して負荷分散」
LoadBalancerにて接続先WEBサーバーを振り分け
ます
サーバー台数が増えた分、合計の
CPU/Memory/Ephemeral Port等が増えるので同時
に対応できるrequest数が増えます...
「Nginxのキャッシュ付きリバースプロキシーで
キャッシュしたContentsを返却する」
response内容をキャッシュしておいて返却します
都度requestを処理してresponse内容をつくるより
もキャッシュからレスポンスするので...
外部の有料サービスである
CDN(Contents Delivery Network)
を利用する
・CDNを簡単に説明すると、クライアントからのアクセスを
変わりに受けてくれるキャッシュサービスです
・全世界に配信サーバーを持っていてクライア...
APIサーバー
scaleup
scaleout
16
「高性能サーバーを利用する」
※WEBサーバーと同様です
APIサーバーはProgramを動作させるので
CPUとMemoryを重視してサーバーを構成します
大量のrequestを受けるWebApplicationの場合、
Scaleupだけだ...
「サーバーを複数台用意して負荷分散」
大量のrequestを受けつつprogramからCacheサ
ーバーやDBへアクセスするので、port枯渇が起
きやすいので APIサーバーのScaleoutは重要で
す
C2ではAPIサーバーを27台使っ...
◆同じユーザー/sessionが同じAPIサーバーに振
り分けられるか保証されない
=>どのサーバーに振り分けられても問題ない作
りにすることが大事
・他
Sticky Sessionを使うとLoadBalancerがcookieを元に同一サ
...
◆Ephemeral port(自由に使える短命port)
の枯渇
Linuxはportを65535まで持っていて、通信などで自由に使え
るportは一般的に 32768 ~ 61000 の 28232個のportを利用可
能です
Epheme...
◆APIサーバーのScaleout最大数 は DBの同時接
続数が限界になる
APIサーバーが多数のrequestを受けられてもDB同時接続数を超
えた際にDB接続待ちが発生してしまう
DBサーバーの限界を超えたAPIサーバー台数を用意しても無...
Cacheサーバー
22
「Query結果をキャッシュ」
DBへの問い合わせを減らすことが出来て、
memoryからキャッシュ情報を取得できるので高
速に処理できる
キャッシュ方法
・memcached
・redis
・file cache
・etc
Cache ~~
...
お手軽でおすすめ
・メモリにキャッシュされ高速にキャッシュ情報を参照可能
・情報の永続化(保存)はできない
・サーバーが故障してもキャッシュなのでサービス継続可能
・memcachedのscaleoutは簡単
クライアント側のmemcahced...
・memoryの不足
memcachedはmemoryにキャッシュするので
memory量を超えて保存できない
・Ephemeral portの枯渇
memcachedへの通信は都度TCPセッションがは
られるのでportの枯渇が起きやすい
=...
高機能でおすすめ
・メモリにキャッシュされ高速にキャッシュ情報を参照可能
・情報の永続化(保存)ができる
・Ranking計算が得意(SortedSet)
・master/slave構成やクラスターを組める
・pub/subもできる
・hype...
・サーバーのmemory以上にキャッシュは出来な
い
Storageに永続化可能でもmemory以上にキャッ
シュすることはできないのでMemory管理が重要
Cache ~Redis/気をつける事~
27
DBサーバー
28
◆DBサーバーを分ける(scaleout)
・Replication(read用DBを増やして負荷分散)
・Vertical Sharding(機能毎にDBを分割)
・Horizontal Sharding(データ毎にDBを分割)
◆データ保存...
登録を担当するMasterDBと参照を担当する
SlaveDBに分けてwriteとreadの負荷分散を行う
MasterDBへの登録がほぼリアルタイムで
SlaveDBへコピーされる(完全に同時ではない)
MySQL(MariaDB), Pos...
◆レプリケーション例
masterDBとslaveDB
一番台数が少ないシンプルな形
DB ~Replication~
master
slave
31
Replication向き
◆レプリケーション例
3レイヤーのレプリケーション構成
masterDB > slave & masterDB > slave
DB ~Replication~
master
slaveslave/
master
slave backup
32...
DBを機能毎に分けて使う(垂直分割)
ユーザー情報をA-DBに、ログ情報をB-DBに保
存するなど
ユーザー情報の参照ならばA-DBへ接続するよ
うにプログラムで開発して実現する
機能毎なのでシンプル
デメリットは1つの機能へのアクセスが多い場...
Programで接続先DBを使い分ける
・User系テーブルならばUserDBへ
・Log系テーブルならばLogDBへ
◆垂直分割例
機能毎にDBを分割
・User系DB
・Log系DB
DB ~Vertical sharding~
slave...
DBをデータ毎に分けて使い分ける(水平分割)
ユーザーIDの剰余(mod)や日付期間等によって登
録するDBサーバーをわける
プログラムで計算して接続先DBを使い分ける
ユーザー情報などデータがルールによって保存
されているDBが変わってしまい...
◆データ毎の水平分割例
[ルール] user_id の 偶数(even) / 奇数(odd) などで分ける
DB ~Horizontal sharding~
slave/
master
slave backup
36
user_id even
...
◆C2での水平分割例
C2ではDB Serverを2セット、DB schemaを8分割しています
[ルール] user_id % 8 で8分割(剰余算 mod)
DB負荷が上がったら最大8台のDB Serverへ分割可能です
※mod 128に...
Table毎に保存するFileをわける
1つのTableの保存領域をルールを決めて複数にわけることで
参照時に目的のデータを探す(Seek)時間が短くなる
Table A
100,000,000(1 hundred million) recor...
CREATE TABLE文
CREATE TABLE `log_training`(
`id` bigint unsigned auto_increment NOT NULL COMMENT '管理用ID'
,`user_id` int uns...
◆ Table partitioningのイメージ図
Table log_training
DB ~table partitioning~
40
1つのTable
保存領域がわか
れている
クエリのWHERE句にuser_idを指定して検索する...
DBは設定できるパラメータが多数あり、要件に合わせて設定
を変更する必要があります
(具体的な設定は section 2 にて)
DB ~設定~
41
Linux Kernel パラメータの変更
・Memory
・OpenできるFile Descripterを増やす
・起動できる Process 数を増やす
・Disk設定
・Network設定
・Ephemeral port を増やす
などの...
Section 2
設定の説明(具体的)
43
WEB/APIサーバー
LoadBalancer
Nginx
php-fpm
44
LoadBalancer
LoadBalancerでアクセスサーバーを振り分ける
Global IP/port と振り分け先のサーバーIP/portを登録する
GlobalIPへのrequestが振り分け先サーバーどれか1台に渡される
(例)G...
LoadBalancer
(例)GMOアプリクラウドでの設定方法 / 振り分けサーバー2台
46
Nginx ~説明~
Nginxは http daemon であり Non blocking I/O
と async I/O により大量のアクセスに対応する
ことが可能
URLによる L7 Load balancing が可能
Luaスクリプト...
Nginx ~conf~
/etc/nginx.conf の重要パラメータ
worker_processes
nginxのプロセスをいくつ起動するか
worker_connections
worker1つあたりの最大接続数
multi_acce...
WebサーバーでPHPを動作させるDaemon
PHPのFastCGI実装の一つ
FPM (FastCGI Process Manager)
FastCGIとは
requet毎に生成破棄されるCGIプロセスを保持するようにし
て高速に再利用でき...
重要な設定
pm.max_children
php-fmpの最大worker数, この値が一番大事!
server memoryが許すまで大きめの値を設定したい
下記コマンドで消費メモリを測定
ps aux | grep php-fpm | a...
ログの確認が重要
負荷テストを行うとエラーログにmax_childrenが足りないな
ど情報が出ていることがある
忘れずに確認しよう
php-fpm ~php-fpm.conf~
51
Cacheサーバー
memcached
Redis
52
Cache ~memcached~
/etc/sysconfig/memcached 重要なパラメータ
MAXCONN = 65535
最大接続数, Ephemeral port以上に設定
CACHESIZE = 3000 (MB)
利用可能物...
Cache ~memcached~
「気をつける事」
・memcachedサーバーは負荷テストを行うとport枯渇により
接続エラーになりやすい
=>サーバー台数を多めに用意するのがおすすめ
・memcachedサーバーへのTCP接続が高負荷な...
重要なパラメータ
maxclients 50000
最大接続数
maxmemory 14gb
最大Memoryサイズ
多数のパラメータがあるが上記は最低限サーバーリソースに
合わせて設定する必要がある
Cache ~Redis~
55
◆ Replication構成は可能な限り3台以上の構成にすることをお
すすめします
1台余剰のSlaveDBがあると
・リアルタイムでDBを参照できる
・エンドユーザーに影響せずに重い集計クエリを実行できる
・DBへの書き込みを止めてBack...
◆ Backupは mysql dir毎コピーを取る方法がおす
すめ
・tarコマンド等で /var/lib/mysql 毎バックアップする
・/var/lib/mysql/master.infoファイルにreplication設定や
binl...
c2の要件において効果が高かったパラメータ
※システム要件によって効果的なパラメータは異なるためシステム毎に要検討
負荷テストにおいて設定した値
max_connections: 10000
connection数上限エラーが発生したためMem...
innodb_lock_wait_timeout: 5
lock待ちが長すぎてconnection上限エラーが発生しやすかったので変更
->5sec以上のlock waitは失敗として終了させて全体が詰まることを減少
innodb_io_cap...
c2でのmy.cnf設定(Ansible template)
character_set_server: utf8mb4
max_connections: 10000
max_connect_errors: 50
transaction-iso...
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size: 2G
innodb_log_buffer_size: 64M
innodb_support_xa:...
# replication
server_id: "{{ ansible_all_ipv4_addresses[0].split('.')[3] }}"
log_slave_updates: ON
# binlog
log_bin: mysql...
Linux Kernel
Parameter
63
Kernel設定の変更によりServer自体の処理性能
が大きくあがります
DB Server や API Server など要件に合わせて
設定を調整することが大切です
※次ページから具体的な設定を紹介します
Kernel設定 ~~
64
重要な Linux kernel設定
net.core.somaxconn=65535
TCP接続数 最大Port数に設定するのがおすすめ
net.ipv4.ip_local_port_range=10000 65535
Ephemeral p...
fs.file-max=10000000
OS全体でOpenできるfile数
kernel.threads-max=1000000
OS全体で起動できるthread数
vm.swappiness=0
Swap処理を積極的に行うどうか 0=可能な...
net.core.netdev_max_backlog=10240
パケット受信時にキューに繋ぐことができるパケットの最大数
net.ipv4.tcp_max_syn_backlog=4096
ソケット当たりのSYNを受け付けてACKを受け取っ...
/etc/security/limits.conf にos user毎にopen可能なfile
descripterや起動できる process数を設定
設定値をあげることで Too many open files エラーが発生しに
くくなる
...
systemdはprocess起動が柔軟に行える
processがOpenできるFile数や起動できるprocess数を動的に
変更可能
大量のfile descripterを必要とするDBサーバー等では上げておく
必要がある
(例)
/etc...
tunedはcentos7から導入された選択されたプロファイルに従っ
てシステム設定を静的および動的にチューニングするデーモン
tuned-admコマンドで設定を変更可能
tuned-adm profile c2
独自のtuned profil...
以上になります
ご清聴ありがとうございました
「cảm ơn」
質問があればどうぞ
(Any Question?)
終わり
71
You’ve finished this document.
Download and read it offline.
Upcoming SlideShare
What to Upload to SlideShare
Next
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

10

Share

高負荷に耐えうるWebApplication Serverの作り方

Download to read offline

高負荷に耐えうる WebApplication の Architecture を設計する際に

・どこで対策するか
・どのように作るか

をご紹介します。

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

高負荷に耐えうるWebApplication Serverの作り方

  1. 1. 高負荷に耐えうる WebApplication Server の作り方 GMOインターネット株式会社 次世代システム研究室 石山 雄太 1/71
  2. 2. Xin chào! Toi ten la Ishiyama Yuta. GMO Internet inc. 次世代システム研究室 (Innovation and Technology System Office) アシスタントマネージャー(Asistant Manager) シニアアーキテクト(Senior Architect) Engineer歴 20年 好き DB / Elixir-lang 自己紹介 2
  3. 3. Goal 高負荷に耐えうる WebApplication の Architecture を設計する際に ・どこで対策するか ・どのように作るか をご紹介します。 Programing codeではなくinfraよりの説明になり ます。高負荷対策は多数ありますが一例とおぼえ ておいていただくことをGoalとしています。 3
  4. 4. section 0 対象とするWebApplicationの説明(前提) section 1 どういった案があるか説明(抽象的) section 2 設定の説明(具体的) pages 71. Agenda 4
  5. 5. Section 0 対象とするWebApplicationの説明(前提) 5
  6. 6. PJ code「C2」 スマートフォン向けゲームのサーバーにて行った負荷 対策を元に説明します ・[OS] CentOS7 ・[WEBサーバー] NGINX ・[APIサーバー] NGINX + PHP-FPM ・[CACHE] Memcached, Redis ・[DB] MySQL(MariaDB) ゲームクライアントとJSON APIおよびHTMLや画像/ 動画をやり取りする構成です 対象とするWebApplication 6
  7. 7. 全体構成図 7 LB API CACHE memcached DB WEB・・・ master ・・ CACHE Redis slave s/m slave backup s/m slave backup s/m slave backup s/m slave backup UserDB01 UserDB02 LogDB02LogDB01 MasterDB01
  8. 8. 全体構成図 ~改善ポイント~ 8 LB API CACHE memcached DB WEB・・・ master ・・ CACHE Redis slave s/m slave backup s/m slave backup s/m slave backup s/m slave backup UserDB01 UserDB02 LogDB02LogDB01 MasterDB01 サーバー 振り分け設定 Scaleout レプリケーション 垂直分割 水平分割 CacheによるDB アクセス削減 Scaleout Replication Ranking
  9. 9. Section 1 どういった案があるか説明(抽象的) 9
  10. 10. ◆ scaleup (1台の性能を上げる) 性能が高いサーバーハードウエアを利用して性 能を上げる ◆ scaleout(台数を増やす) サーバーを増やして合計の処理性能を上げる ◆ 他 programing codeの最適化 OS / Middleware のconfig最適化 基本 ~~ 10
  11. 11. WEBサーバー scaleup scaleout キャッシュ付きreverse proxy CDN 11
  12. 12. 「高性能サーバーを利用する」 静的HTMLや画像や動画ファイルなどContentsを配信するWEBサ ーバーにおいて、scaleup時に重要視するのは、 CPU clock/core数です Memoryはswapしない程度にあれば大丈夫です CPU core数が多いと一度に複数のrequestに対応できるので有利 です WEBサーバー ~scaleup~ 12
  13. 13. 「サーバーを複数台用意して負荷分散」 LoadBalancerにて接続先WEBサーバーを振り分け ます サーバー台数が増えた分、合計の CPU/Memory/Ephemeral Port等が増えるので同時 に対応できるrequest数が増えます WEBサーバー ~scaleout~ 13
  14. 14. 「Nginxのキャッシュ付きリバースプロキシーで キャッシュしたContentsを返却する」 response内容をキャッシュしておいて返却します 都度requestを処理してresponse内容をつくるより もキャッシュからレスポンスするので高速です ※C2では次で紹介するCDNを使うので Nginxでの キャッシュは行っていません WEBサーバー ~Contents Cached Reverse Proxy~ 14
  15. 15. 外部の有料サービスである CDN(Contents Delivery Network) を利用する ・CDNを簡単に説明すると、クライアントからのアクセスを 変わりに受けてくれるキャッシュサービスです ・全世界に配信サーバーを持っていてクライアントから一番 近いサーバーでContentsキャッシュをレスポンスしてくれま す ・DDoS攻撃への対応も可能 ・Akamai、AWS CloudFront が有名 こちらは有料なだけあって非常に効果が高い おすすめ WEBサーバー ~CDN~ 15
  16. 16. APIサーバー scaleup scaleout 16
  17. 17. 「高性能サーバーを利用する」 ※WEBサーバーと同様です APIサーバーはProgramを動作させるので CPUとMemoryを重視してサーバーを構成します 大量のrequestを受けるWebApplicationの場合、 Scaleupだけだと厳しいです API ~Scaleup~ 17 API server API 1 API 1 cpu/mem up!
  18. 18. 「サーバーを複数台用意して負荷分散」 大量のrequestを受けつつprogramからCacheサ ーバーやDBへアクセスするので、port枯渇が起 きやすいので APIサーバーのScaleoutは重要で す C2ではAPIサーバーを27台使っています API ~Scaleout~ 18 API servers API 1 API 2 API 3 API ... API 27
  19. 19. ◆同じユーザー/sessionが同じAPIサーバーに振 り分けられるか保証されない =>どのサーバーに振り分けられても問題ない作 りにすることが大事 ・他 Sticky Sessionを使うとLoadBalancerがcookieを元に同一サ ーバーへ振り分けてくれますが、クラウドサービスによって Sticky Session の Cookie Expire 時間が短いなど問題になる こともあるので可能な限りどのAPIサーバーに振り分けられ ても問題がないように設計したほうが良い API ~Scaleout/気をつける事~ 19
  20. 20. ◆Ephemeral port(自由に使える短命port) の枯渇 Linuxはportを65535まで持っていて、通信などで自由に使え るportは一般的に 32768 ~ 61000 の 28232個のportを利用可 能です Ephemeral portが全て使われてしまうと使えるportがないた めに新しい通信を行うことができなくなります =>kernelパラメータにてEphemeral portを増やすことが可能 API ~Scaleout/気をつける事~ 20
  21. 21. ◆APIサーバーのScaleout最大数 は DBの同時接 続数が限界になる APIサーバーが多数のrequestを受けられてもDB同時接続数を超 えた際にDB接続待ちが発生してしまう DBサーバーの限界を超えたAPIサーバー台数を用意しても無駄 になってしまう =>DBのスループットを上げることが大事 =>遅いQueryを投げてしまうとDBが詰まりやすくなるので Programで実行するQueryの最適化も大事 API ~scaleout/気をつける事~ 21
  22. 22. Cacheサーバー 22
  23. 23. 「Query結果をキャッシュ」 DBへの問い合わせを減らすことが出来て、 memoryからキャッシュ情報を取得できるので高 速に処理できる キャッシュ方法 ・memcached ・redis ・file cache ・etc Cache ~~ 23
  24. 24. お手軽でおすすめ ・メモリにキャッシュされ高速にキャッシュ情報を参照可能 ・情報の永続化(保存)はできない ・サーバーが故障してもキャッシュなのでサービス継続可能 ・memcachedのscaleoutは簡単 クライアント側のmemcahced libraryで勝手に接続先サーバー を決めてくれる 登録するkey毎にハッシュ値を求めてserver数の剰余(mod)でサ ーバを決定 Cache ~memcached~ 24
  25. 25. ・memoryの不足 memcachedはmemoryにキャッシュするので memory量を超えて保存できない ・Ephemeral portの枯渇 memcachedへの通信は都度TCPセッションがは られるのでportの枯渇が起きやすい =>memcachedサーバーを多めに用意する 3台だと接続エラーが出たため9台へ増やした Cache ~memcached/気をつける事~ 25
  26. 26. 高機能でおすすめ ・メモリにキャッシュされ高速にキャッシュ情報を参照可能 ・情報の永続化(保存)ができる ・Ranking計算が得意(SortedSet) ・master/slave構成やクラスターを組める ・pub/subもできる ・hyperloglogアルゴリズムによりデータのcardinalityを高速に 推定できる(ユニークユーザー数など) ・シングルスレッドモデルなので排他制御を考えなくてよい =>C2ではランキングに利用 Cache ~Redis~ 26
  27. 27. ・サーバーのmemory以上にキャッシュは出来な い Storageに永続化可能でもmemory以上にキャッ シュすることはできないのでMemory管理が重要 Cache ~Redis/気をつける事~ 27
  28. 28. DBサーバー 28
  29. 29. ◆DBサーバーを分ける(scaleout) ・Replication(read用DBを増やして負荷分散) ・Vertical Sharding(機能毎にDBを分割) ・Horizontal Sharding(データ毎にDBを分割) ◆データ保存領域を分ける ・table partitioning ◆設定 DB設定の最適化 OS設定の最適化 DB ~負荷対策案~ 29
  30. 30. 登録を担当するMasterDBと参照を担当する SlaveDBに分けてwriteとreadの負荷分散を行う MasterDBへの登録がほぼリアルタイムで SlaveDBへコピーされる(完全に同時ではない) MySQL(MariaDB), PostgreSQLなど主要なDBは Replicationに対応している DB ~Replication~ 30
  31. 31. ◆レプリケーション例 masterDBとslaveDB 一番台数が少ないシンプルな形 DB ~Replication~ master slave 31 Replication向き
  32. 32. ◆レプリケーション例 3レイヤーのレプリケーション構成 masterDB > slave & masterDB > slave DB ~Replication~ master slaveslave/ master slave backup 32 Replication向きSlaveDBがMasterDB を兼ねることも可能
  33. 33. DBを機能毎に分けて使う(垂直分割) ユーザー情報をA-DBに、ログ情報をB-DBに保 存するなど ユーザー情報の参照ならばA-DBへ接続するよ うにプログラムで開発して実現する 機能毎なのでシンプル デメリットは1つの機能へのアクセスが多い場 合に分割出来ない DB ~Vertical sharding~ 33
  34. 34. Programで接続先DBを使い分ける ・User系テーブルならばUserDBへ ・Log系テーブルならばLogDBへ ◆垂直分割例 機能毎にDBを分割 ・User系DB ・Log系DB DB ~Vertical sharding~ slave/ master slave backup 34 User系DB slave/ master slave backup Log系DB API PHP-FPM
  35. 35. DBをデータ毎に分けて使い分ける(水平分割) ユーザーIDの剰余(mod)や日付期間等によって登 録するDBサーバーをわける プログラムで計算して接続先DBを使い分ける ユーザー情報などデータがルールによって保存 されているDBが変わってしまい開発や運用が大 変 メリットは論理的にいくつでも分割可能 DB ~Horizontal sharding~ 35
  36. 36. ◆データ毎の水平分割例 [ルール] user_id の 偶数(even) / 奇数(odd) などで分ける DB ~Horizontal sharding~ slave/ master slave backup 36 user_id even slave/ master slave backup user_id odd API PHP-FPM Programで接続先DB を使い分ける
  37. 37. ◆C2での水平分割例 C2ではDB Serverを2セット、DB schemaを8分割しています [ルール] user_id % 8 で8分割(剰余算 mod) DB負荷が上がったら最大8台のDB Serverへ分割可能です ※mod 128にすれば128台へ分割可能ですが管理が大変なのでほどほどに... DB ~Horizontal sharding/c2~ slave/ master slave backup 37 db 00,02,04,06 を保存 slave/ master slave backup db 01,03,05,07 を保存 API PHP-FPM Programでルールに合わせて接続先DB を使い分ける mod 0,2,4,6ならば server1mへ mod 1,3,5,7ならば server2mへ 00 02 04 06 00 02 04 06 01 03 05 07 01 03 05 07 [db server1m] [db server1s] [db server2s] [db server2m]
  38. 38. Table毎に保存するFileをわける 1つのTableの保存領域をルールを決めて複数にわけることで 参照時に目的のデータを探す(Seek)時間が短くなる Table A 100,000,000(1 hundred million) records ↓ Table A[partition] 1,000,000(1 million) × 100[partition] =>ルールに沿った検索だと 1partitionのみ参照すれば良い! MySQLではルールとしてPrimary Keyにpartition rule columnを 含める必要がある DB ~table partitioning~ 38
  39. 39. CREATE TABLE文 CREATE TABLE `log_training`( `id` bigint unsigned auto_increment NOT NULL COMMENT '管理用ID' ,`user_id` int unsigned NOT NULL COMMENT 'ユーザーID' ,`mst_training_id` int unsigned NOT NULL COMMENT '特訓ID' ,`type` int unsigned NOT NULL COMMENT '種別(0:消費、1:付与、2:売却)' ,`amount` int NOT NULL COMMENT '増減量' ,`count` int unsigned NOT NULL COMMENT '個数' ,`created` datetime NOT NULL COMMENT '登録日時' ,PRIMARY KEY(`id`, `user_id`) ,KEY log_training_idx1(`user_id`) ,KEY log_training_idx2(`mst_training_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='特訓ログ' PARTITION BY HASH(MOD(`user_id`, 100)) PARTITIONS 100; ※ user_idを100で割った余りでpartition100個を入れ分けている ※ 主キーにpartition ルールで使っているuser_idカラムを含めている DB ~table partitioning~ 39
  40. 40. ◆ Table partitioningのイメージ図 Table log_training DB ~table partitioning~ 40 1つのTable 保存領域がわか れている クエリのWHERE句にuser_idを指定して検索すると 該当の領域のみSeekする [ルール] user_id % 100 ・mod 0 -> 00の領域へ保存 ・mod 1 -> 01の領域へ保存 ・mod 99-> 99の領域へ保存 00 X [Table log_training] 01 03 04 05 06 99 保存領域
  41. 41. DBは設定できるパラメータが多数あり、要件に合わせて設定 を変更する必要があります (具体的な設定は section 2 にて) DB ~設定~ 41
  42. 42. Linux Kernel パラメータの変更 ・Memory ・OpenできるFile Descripterを増やす ・起動できる Process 数を増やす ・Disk設定 ・Network設定 ・Ephemeral port を増やす などの設定を行います (具体的な設定は section 2 にて) Linux 設定 42
  43. 43. Section 2 設定の説明(具体的) 43
  44. 44. WEB/APIサーバー LoadBalancer Nginx php-fpm 44
  45. 45. LoadBalancer LoadBalancerでアクセスサーバーを振り分ける Global IP/port と振り分け先のサーバーIP/portを登録する GlobalIPへのrequestが振り分け先サーバーどれか1台に渡される (例)GMOアプリクラウドでの設定方法 45
  46. 46. LoadBalancer (例)GMOアプリクラウドでの設定方法 / 振り分けサーバー2台 46
  47. 47. Nginx ~説明~ Nginxは http daemon であり Non blocking I/O と async I/O により大量のアクセスに対応する ことが可能 URLによる L7 Load balancing が可能 LuaスクリプトやC言語で独自の判定処理を実装 出来て複雑な処理も可能 47
  48. 48. Nginx ~conf~ /etc/nginx.conf の重要パラメータ worker_processes nginxのプロセスをいくつ起動するか worker_connections worker1つあたりの最大接続数 multi_accept on requestを同時に受けられるようにする use epoll requestの状態変化をkernelに任せて次の処理 を行う(Linux システムコール) 48
  49. 49. WebサーバーでPHPを動作させるDaemon PHPのFastCGI実装の一つ FPM (FastCGI Process Manager) FastCGIとは requet毎に生成破棄されるCGIプロセスを保持するようにし て高速に再利用できるようにした仕組み php-fpm ~説明~ 49
  50. 50. 重要な設定 pm.max_children php-fmpの最大worker数, この値が一番大事! server memoryが許すまで大きめの値を設定したい 下記コマンドで消費メモリを測定 ps aux | grep php-fpm | awk '{sum += $6} END {print sum}' pm.start_servers 起動時に作成するworker数 pm.min_spare_servers 維持する最小worker数 pm.process_idle_timeout workerを停止するまでのidle時間min_spare_servers数 php-fpm ~php-fpm.conf~ 50
  51. 51. ログの確認が重要 負荷テストを行うとエラーログにmax_childrenが足りないな ど情報が出ていることがある 忘れずに確認しよう php-fpm ~php-fpm.conf~ 51
  52. 52. Cacheサーバー memcached Redis 52
  53. 53. Cache ~memcached~ /etc/sysconfig/memcached 重要なパラメータ MAXCONN = 65535 最大接続数, Ephemeral port以上に設定 CACHESIZE = 3000 (MB) 利用可能物理Memory以内で設定 53
  54. 54. Cache ~memcached~ 「気をつける事」 ・memcachedサーバーは負荷テストを行うとport枯渇により 接続エラーになりやすい =>サーバー台数を多めに用意するのがおすすめ ・memcachedサーバーへのTCP接続が高負荷な状況ではスルー プット低下の要因になることがある =>固定値のキャッシュはAPIサーバーlocalに構築した memcahcedにCacheするのがおすすめ ※C2ではプログラムで都度値が変わるCacheをCacheサーバー へ、table meta情報や値が変わらないmaster情報をlocalhostへ キャッシュしている 54
  55. 55. 重要なパラメータ maxclients 50000 最大接続数 maxmemory 14gb 最大Memoryサイズ 多数のパラメータがあるが上記は最低限サーバーリソースに 合わせて設定する必要がある Cache ~Redis~ 55
  56. 56. ◆ Replication構成は可能な限り3台以上の構成にすることをお すすめします 1台余剰のSlaveDBがあると ・リアルタイムでDBを参照できる ・エンドユーザーに影響せずに重い集計クエリを実行できる ・DBへの書き込みを止めてBackupを取得できる ・MasterDBが壊れた際の予備にできる などが可能になります (1)masterDB(エンドユーザー向け) (2)slaveDB(エンドユーザー向け) (3)slaveDB(社内向け / KPI参照 / Backupを取得 / 故障時の代替サーバー) DB ~気をつける事 1/2~ 56
  57. 57. ◆ Backupは mysql dir毎コピーを取る方法がおす すめ ・tarコマンド等で /var/lib/mysql 毎バックアップする ・/var/lib/mysql/master.infoファイルにreplication設定や binlog positionが記入されているため、masterDBにbinlogファ イルが残っていればバックアップから最新状態まで復旧可能 DB ~気をつける事 2/2~ 57
  58. 58. c2の要件において効果が高かったパラメータ ※システム要件によって効果的なパラメータは異なるためシステム毎に要検討 負荷テストにおいて設定した値 max_connections: 10000 connection数上限エラーが発生したためMemoryが許す範囲で高く持った -> connectionエラーが減った transaction-isolation: READ-COMMITTED lock待ちになることが多くあったため変更 ->lock待ちが減った ※C2の要件的にこの分離レベルで問題がないため設定 innodb_buffer_pool_instances: 16 ->若干qpsが向上した DB ~my.cnf / 効果あり 1/2~ 58
  59. 59. innodb_lock_wait_timeout: 5 lock待ちが長すぎてconnection上限エラーが発生しやすかったので変更 ->5sec以上のlock waitは失敗として終了させて全体が詰まることを減少 innodb_io_capacity_max: 30000 innodb_io_capacity: 20000 Fusion ioMemory向け設定 ※io_capacityを100000など高い値にすると2回目以降の高負荷時にqpsが50%ほど 下がる減少が発生した innodb_buffer_pool_size: 64G conneciton毎に必要とするメモリなど他仕様メモリを引いた残りのメモリの80% で設定 ->DB serverはswapを発生させてはならない innodb_flush_method: O_DIRECT osのpage cacheを使わずに直接writeする, innodbでは DB ~my.cnf / 効果あり 2/2~ 59
  60. 60. c2でのmy.cnf設定(Ansible template) character_set_server: utf8mb4 max_connections: 10000 max_connect_errors: 50 transaction-isolation: READ-COMMITTED # innodb innodb_buffer_pool_size: 64G innodb_buffer_pool_instances: 16 innodb_flush_method: O_DIRECT innodb_flush_log_at_trx_commit: 1 innodb_file_per_table: 1 innodb_data_file_path: ibdata1:10M:autoextend innodb_file_format: Barracuda open_files_limit: 163840 innodb_open_files: 128000 DB ~my.cnf 1/3~ 60
  61. 61. # Set .._log_file_size to 25 % of buffer pool size innodb_log_file_size: 2G innodb_log_buffer_size: 64M innodb_support_xa: 1 innodb_lock_wait_timeout: 5 # io threads 並列化可能な状況ならば max64 以内で設定 innodb_write_io_threads: 16 innodb_read_io_threads: 16 innodb_thread_concurrency: 0 # fusion-io/SSD innodb_io_capacity_max: 30000 innodb_io_capacity: 20000 # memory sort_buffer_size: 2M join_buffer_size: 2M read_buffer_size: 1M max_allowed_packet: 4M DB ~my.cnf 2/3~ 61
  62. 62. # replication server_id: "{{ ansible_all_ipv4_addresses[0].split('.')[3] }}" log_slave_updates: ON # binlog log_bin: mysql-bin binlog_format: MIXED expire_logs_days: 180 max_binlog_size: 500MB DB ~my.cnf 3/3~ 62
  63. 63. Linux Kernel Parameter 63
  64. 64. Kernel設定の変更によりServer自体の処理性能 が大きくあがります DB Server や API Server など要件に合わせて 設定を調整することが大切です ※次ページから具体的な設定を紹介します Kernel設定 ~~ 64
  65. 65. 重要な Linux kernel設定 net.core.somaxconn=65535 TCP接続数 最大Port数に設定するのがおすすめ net.ipv4.ip_local_port_range=10000 65535 Ephemeral portを設定、上記だとdefault 28000のところを55000使えるように なる net.ipv4.tcp_fin_timeout=5 TCPセッションがFIN-WAIT2からTIME_WAITへ変化する時間 net.ipv4.tcp_tw_reuse=1 TIME_WAIT状態のportの再利用を行う(接続先IP/portが同じサーバーの場合に 再利用可能) =>上記設定で同時通信数の最大化やport枯渇対策が可能 Kernel設定 ~/etc/sysctl.conf 1/3~ 65
  66. 66. fs.file-max=10000000 OS全体でOpenできるfile数 kernel.threads-max=1000000 OS全体で起動できるthread数 vm.swappiness=0 Swap処理を積極的に行うどうか 0=可能な限り物理メモリ枯渇するまでswapしない kernel.shmmax=68719476736 kernel.shmall=4294967296 共通メモリー設定 Kernel設定 ~/etc/sysctl.conf 2/3~ 66
  67. 67. net.core.netdev_max_backlog=10240 パケット受信時にキューに繋ぐことができるパケットの最大数 net.ipv4.tcp_max_syn_backlog=4096 ソケット当たりのSYNを受け付けてACKを受け取っていない状態のコネクションの 保持可能数 net.ipv4.tcp_keepalive_time=65 net.ipv4.tcp_keepalive_probes=4 net.ipv4.tcp_keepalive_intvl=5 tcp接続維持設定、65sec維持したあと5sec毎に4回確認して応答がなければTCP接 続を切断する Kernel設定 ~/etc/sysctl.conf 3/3~ 67
  68. 68. /etc/security/limits.conf にos user毎にopen可能なfile descripterや起動できる process数を設定 設定値をあげることで Too many open files エラーが発生しに くくなる (例) os user c2の file descripterとprocess数の上限を変更 c2 soft nofile 65535 c2 hard nofile 65535 c2 soft nproc 1006500 c2 hard nproc 1006500 Kernel設定 ~limits.conf~ 68
  69. 69. systemdはprocess起動が柔軟に行える processがOpenできるFile数や起動できるprocess数を動的に 変更可能 大量のfile descripterを必要とするDBサーバー等では上げておく 必要がある (例) /etc/systemd/system/mariadb.service.d/XXXX.conf [Service] LimitNOFILE=1006500 LimitNPROC=1006500 ※上限値1006500まで指定しておくのがおすすめ Kernel設定 ~systemd~ 69
  70. 70. tunedはcentos7から導入された選択されたプロファイルに従っ てシステム設定を静的および動的にチューニングするデーモン tuned-admコマンドで設定を変更可能 tuned-adm profile c2 独自のtuned profileを作ることが可能 /usr/lib/tuned/c2/tuned.conf tuned [main] include= throughput-performance [vm] transparent_hugepages=never vm.swappiness=0 c2では throughput-performance profileを継承して transparent_hupageのキャンセル や可能なかぎりスワップしない設定を追加しています Kernel設定 ~tuned~ 70
  71. 71. 以上になります ご清聴ありがとうございました 「cảm ơn」 質問があればどうぞ (Any Question?) 終わり 71
  • xiuzuo

    Sep. 8, 2021
  • HishikawaTakuro

    Oct. 28, 2020
  • kazzpapa3

    Sep. 7, 2020
  • kazzpapa3

    Sep. 7, 2020
  • ssuserf051131

    Sep. 4, 2020
  • togattti

    May. 26, 2020
  • miffy2013

    May. 22, 2020
  • ToshinariSato

    Apr. 3, 2019
  • takasick

    Apr. 2, 2019
  • nguyendinhhung1710

    Oct. 24, 2018

高負荷に耐えうる WebApplication の Architecture を設計する際に ・どこで対策するか ・どのように作るか をご紹介します。

Views

Total views

3,709

On Slideshare

0

From embeds

0

Number of embeds

768

Actions

Downloads

23

Shares

0

Comments

0

Likes

10

×