Webアプリケーションの パフォーマンス向上のコツ 実践編
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Webアプリケーションの パフォーマンス向上のコツ 実践編

on

  • 15,663 views

 

Statistics

Views

Total Views
15,663
Views on SlideShare
3,940
Embed Views
11,723

Actions

Likes
33
Downloads
26
Comments
0

18 Embeds 11,723

http://isucon.net 7025
http://blog.nomadscafe.jp 3491
http://blog.en30.net 414
http://rkmathi.hatenablog.com 270
https://twitter.com 239
http://localhost 87
http://chieko.aa-dev.com 63
http://keens.github.io 55
http://feedly.com 49
http://nomadscafe.jp 8
http://nomadscafe1.rssing.com 6
https://www.inoreader.com 4
http://s.deeeki.com 4
http://news.google.com 3
https://kcw.kddi.ne.jp 2
http://fl.ssig33.com 1
http://www.inoreader.com 1
http://www.peeep.us 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Webアプリケーションの パフォーマンス向上のコツ 実践編 Presentation Transcript

  • 1. Webアプリケーションの パフォーマンス向上のコツ 実践編 ISUCON夏期講習 2014/8/20 Masahiro Nagano
  • 2. 午前3時ぐらいまで 挑戦してみました
  • 3. 最終スコア 9246
  • 4. やってみたことを 紹介します
  • 5. 初期スコア 1664
  • 6. (1) 環境整備
  • 7. 静的コンテンツを Reverse Proxy で配信 Reverse Proxy: クライアントからの接続を 受け、Applicationサーバに処理を中継す る。画像,js,css などの静的コンテンツを返す 役割もある Application Server: ユーザからのリクエス トを受けて適切なページを構築・レスポン スを行う
  • 8. $ cat /etc/httpd/conf.d/isucon.conf <VirtualHost *:80> DocumentRoot /home/isu-user/isucon/webapp/public RewriteEngine on RewriteCond REQUEST_URI !^/favicon.ico$ RewriteCond REQUEST_URI !^/(img|css|js)/ RewriteRule /(.*)$ http://localhost:5000/$1 [P] </VirtualHost> command
  • 9. スコア 1664 => 1719
  • 10. Nginx 化 • オープンソースのWebサーバ。高速に動 作し、メモリ使用量がすくないなどの 特徴があります
  • 11. Apache vs. Nginx worker worker worker worker worker worker worker worker worker リクエスト コンテキストスイッチが 大量発生 リクエスト worker 1個のプロセスで 効率よく通信を処理
  • 12. $ sudo yum install nginx $ sudo service httpd stop [program:nginx] directory=/ command=/usr/sbin/nginx -c /home/isu-user/isucon/ nginx.conf autostart = true command run.ini nginx.confはのちほど公開します
  • 13. スコア 1719 => 1764
  • 14. (2) Perl にします ワタシハパールチョットデキル
  • 15. Perl の起動方法 command=/home/../isucon/env.sh carton exec -- start_server --path /tmp/app.sock -- plackup -s Starlet --max-workers 4 --max-reqs-per-child 50000 -E production -a app.psgi run.ini TCPではなくUNIXdomain socketを使う プロセスを長生きさせる プロセスはあげすぎない
  • 16. TCPの接続は高コスト Reverse Proxy App Server リクエスト毎に threewayhandshake
  • 17. スコア 1764 => 1891
  • 18. (3) アプリをみよう
  • 19. “/” “/recent/xxx” “/memo/xxxx” “/mypage”
  • 20. “/” “/recent/xxx” “/memo/xxxx” “/mypage” DBへの問い合わせが重い markdownの変換に プロセス起動 DBへの問い合わせが 若干重い
  • 21. (4) 外部プロセス起動
  • 22. +use Text::Markdown::Hoedown qw//; sub markdown { my $content = shift; - my ($fh, $filename) = tempfile(); - $fh->print(encode_utf8($content)); - $fh->close; - my $html = qx{ ../bin/markdown $filename }; - unlink $filename; - return $html; + Text::Markdown::Hoedown::markdown($content) } webapp/perl/lib/Isucon3/Web.pm ここがmarkdownコマンドを 起動している “/memo/xxxx”
  • 23. スコア 1891 => 2233
  • 24. (5) N+1 クエリ
  • 25. my $memos = $self->dbh->select_all( 'SELECT * FROM memos WHERE is_private=0 ORDER BY created_at DESC, id DESC LIMIT 100' ); for my $memo (@$memos) { $memo->{username} = $self->dbh->select_one( 'SELECT username FROM users WHERE id=?', $memo->{user}, ); } webapp/perl/lib/Isucon3/Web.pm 100回ルーーーープ “/”
  • 26. use the join, luke
  • 27. id user_id id name memosテーブル usersテーブル id user_id name memos JOIN users ON memos.user_id = user.id
  • 28. my $memos = $self->dbh->select_all( 'SELECT memos.*,users.username FROM memos JOIN users ON memos.user = users.id WHERE memos.is_private=0 ORDER BY memos.created_at DESC, memos.id DESC LIMIT 100' ); webapp/perl/lib/Isucon3/Web.pm “/”,“/recent”
  • 29. スコア 2233 => 2398
  • 30. (6) インデックス
  • 31. SELECT * FROM memos WHERE is_private=0 ORDER BY created_at DESC LIMIT 100 id is_priv ate ... 0 0 1 0 1 memosテーブル id is_priv ate ... 0 0 0 SORT webapp/perl/lib/Isucon3/Web.pm indexがないと
  • 32. indexをつくる cat <<'EOF' | mysql -u isucon isucon ALTER TABLE memos ADD INDEX (is_private,created_at); EOF init.sh
  • 33. B-Tree 0 1is_private created_at older newer older newer
  • 34. B-Tree 0 1is_private created_at older newer older newer
  • 35. B-Tree 0 1is_private created_at older newer older newer
  • 36. B-Tree 0 1is_private created_at older newer older newer
  • 37. スコア 2398 => 2668
  • 38.  (7) タイトル生成
  • 39. これ
  • 40. mysql> show create table memosG *************************** 1. row *************************** Table: memos Create Table: CREATE TABLE `memos` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user` int(11) NOT NULL, `content` text, `is_private` tinyint(4) NOT NULL DEFAULT '0', `created_at` datetime NOT NULL, `updated_at` timestamp NOT NULL DEFAULT, PRIMARY KEY (`id`), ) ENGINE=InnoDB AUTO_INCREMENT=41311 DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql titleカラムが存在しない!
  • 41. <: $memo.content.split('r?n').first() :> webapp/perl/views/index.tx splitでCPU使用contentの転送で通信
  • 42. cat <<'EOF' | mysql -u isucon isucon ALTER TABLE memos ADD COLUMN title text; UPDATE memos SET title = substring_index(content,"n",1); EOF init.sh titleカラムの追加
  • 43. POST時に保存 $self->dbh->query(   'INSERT INTO memos (user, title, content, is_private, created_at) VALUES (?, ?, ?, ?, now()) ', $user_id, (split /r?n/, $content)[0], $content, $is_private, ); webapp/perl/lib/Isucon3/Web.pm
  • 44. my $memos = $self->dbh->select_all( 'SELECT memos.id, memos.title, memos.is_private, memos.created_at, users.username FROM memos JOIN users ON memos.user = users.id WHERE memos.is_private=0 ORDER BY memos.created_at DESC, memos.id DESC LIMIT 100' ); webapp/perl/lib/Isucon3/Web.pm “/”,“/recent” memos.*だとcontentを 取ってしまう
  • 45. スコア 2668 => 3060
  • 46. そして戦いは続く
  • 47. Next Conan's HINT
  • 48. “/mypage”の インデックス
  • 49. 以上。