Upload
masahiro-nagano
View
6.273
Download
1
Embed Size (px)
DESCRIPTION
Citation preview
『How to build a High Performance
PSGI/Plack Server』のその後とISUCON3を受けての話題
Shibuya Plack/PSGI Conference (shibuya.pl) #1 #plackconMasahiro Nagano @kazeburo
13年11月20日水曜日
Me• 長野雅広 Masahiro Nagano
• @kazeburo
• PAUSE: KAZEBURO
• Operations Engineer, Site Reliability
• LINE Corp.Development support on LINE Familly, livedoor
13年11月20日水曜日
ISUCON3 優勝しました!
We used nginx, Proclet, Starlet, Imager, Kossy
13年11月20日水曜日
WEB+DB PRESS Vol.78(2013年12月発売)Perl Hackers Hub
【第23回】Plack/PSGI 実践入門
13年11月20日水曜日
YAPC::Asia 2013 Tokyo
http://www.slideshare.net/kazeburo/yapc2013psgi-plack13年11月20日水曜日
Summary of Slide
• Monoceros
• Plack/PSGI Basics
• How to build a high performance PSGI/Plack server
• Introduction of PSGI servers on CPAN
13年11月20日水曜日
Performance Techniques for PSGI/Plack server
• Prefork
• no accept serialization
• TCP_DEFER_ACCEPT
• non blocking IO / reduce system calls
• XS HTTP Parser
• TCP_NODELAY
13年11月20日水曜日
その後にやったこと
13年11月20日水曜日
Monoceros 編
13年11月20日水曜日
1. accept4(2)
13年11月20日水曜日
13年11月20日水曜日
Set FD_CLOEXEC and O_NONBLOCK in one system call
select(16, [4 10], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 999997})
accept(4, {sa_family=AF_INET, sin_port=htons(41296), sin_addr=inet_addr("127.0.0.1")}, [16]) = 6ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument)lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument)lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
fcntl(6, F_SETFD, FD_CLOEXEC) = 0fcntl(6, F_SETFL, O_RDONLY|O_NONBLOCK) = 0setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0read(6, "GET / HTTP/1.0\r\nHost: localhost:"..., 131072) = 82
gettimeofday({1381121587, 895814}, NULL) = 0write(6, "HTTP/1.1 200 OK\r\nDate: Mon, 07 O"..., 112) = 112
close(6) = 0
13年11月20日水曜日
Set FD_CLOEXEC and O_NONBLOCK in one system call
select(16, [4 10], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 999997})
accept4(4, {sa_family=AF_INET, sin_port=htons(42605), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC|SOCK_NONBLOCK) = 6ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument)
lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument)
lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0
read(6, "GET / HTTP/1.0\r\nHost: localhost:"..., 131072) = 82gettimeofday({1381121587, 895814}, NULL) = 0
write(6, "HTTP/1.1 200 OK\r\nDate: Mon, 07 O"..., 112) = 112close(6) = 0
13年11月20日水曜日
パフォーマンスの変化はなかった。。。
13年11月20日水曜日
2. :unix PerlIO
13年11月20日水曜日
select(16, [4 10], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 999997})
accept4(4, {sa_family=AF_INET, sin_port=htons(42605), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC|SOCK_NONBLOCK) = 6
ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument)
lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffc03016c0) = -1 EINVAL (Invalid argument)
lseek(6, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0
read(6, "GET / HTTP/1.0\r\nHost: localhost:"..., 131072) = 82
gettimeofday({1381121587, 895814}, NULL) = 0
write(6, "HTTP/1.1 200 OK\r\nDate: Mon, 07 O"..., 112) = 112
close(6) = 0
何コレ?
13年11月20日水曜日
:perlio adds these
13年11月20日水曜日
sub do_accept { my $self = shift; use open 'IO' => ':unix'; my ($conn,$peer); $peer = accept4($conn,$self->{listen_sock}); return ($conn, $peer);}
:unix PerlIO
13年11月20日水曜日
select(16, [4 10], NULL, NULL, {1, 0}) = 1 (in [4], left {0, 999997})
accept4(4, {sa_family=AF_INET, sin_port=htons(42605), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC|SOCK_NONBLOCK) = 6
setsockopt(6, SOL_TCP, TCP_NODELAY, [1], 4) = 0
read(6, "GET / HTTP/1.0\r\nHost: localhost:"..., 131072) = 82
gettimeofday({1381121587, 895814}, NULL) = 0
write(6, "HTTP/1.1 200 OK\r\nDate: Mon, 07 O"..., 112) = 112
close(6) = 0
:unix PerlIO
13年11月20日水曜日
パフォーマンスほぼ変わらなかった。。。
13年11月20日水曜日
3. send!le(2)
13年11月20日水曜日
13年11月20日水曜日
read(7, "GET /static/jquery-1.10.2.min.js"..., 131072) = 185
open("./jquery-1.10.2.min.js.gz", O_RDONLY) = 9
write(7, "HTTP/1.1 200 OK\r\nDate: Wed, 20 N"..., 213) = 213
read(9, "\37\213\10\10\344\207\361Q\0\3jquery-1.10.2.min.js\0\254"..., 8192) = 8192
read(9, "\340\263\2542\327\315d\344\v\321\6jY\346"..., 8192) = 8192
read(9, "\2335|G\3i\1\204\205?\374\2514[,}u\235"..., 8192) = 8192
read(9, "\361\307N-\ns\254\212\370p)`*\276\276"..., 8192) = 8192
read(9, "\250\273\23\263k\1\0", 8192) = 7
read(9, "", 8192) = 0
brk(0x2eed000) = 0x2eed000
write(7, "\37\213\10\10\344\207\361Q\0\3jquery-1.10.2.min.js\0\254"..., 32775) = 32775
close(7) = 0
13年11月20日水曜日
read(7, "GET /static/jquery-1.10.2.min.js"..., 131072) = 185open("./jquery-1.10.2.min.js.gz", O_RDONLY) = 9write(7, "HTTP/1.1 200 OK\r\nDate: Wed, 20 N"..., 213) = 213lseek(9, 0, SEEK_CUR) = 0
sendfile(7, 9, [0], 32775) = 32775close(7) = 0
13年11月20日水曜日
send!le(2) benchmark
0
375
750
1125
1500 1471
1121
no-send!le send!le
jquery-min.js(90KB) Req/Sec
13年11月20日水曜日
ISUCON3 編
13年11月20日水曜日
ISUCON3予選のPerlアプリケーションの初期スコアがRubyのそれより悪かったのでごにょごにょやっていた
0
750
1500
2250
3000
865
2361
Ruby/Perl 初期スコア
Ruby Perl
13年11月20日水曜日
やったこと✓Kossy
✓uri_forのキャッシュ
✓Response->!nalizeの最適化
✓Plack::Middleware::Session::Simple
✓Monocerosアップデート
✓改造Starlet
13年11月20日水曜日
改造 Starlet の中身https://github.com/kazeburo/isucon3quali!er-myhack/blob/master/lib/Starlet/Server.pm
13年11月20日水曜日
改造 Starlet
• no use IO::Socket’s methods
• AnyEvent::Util::fh_nonblocking
• accept4(2)
• send!le(2)
• supports unix domain socket(starmanはサポートしている)
13年11月20日水曜日
unix domain socket
$ plackup -s Starlet \ --socket-path /tmp/app.sock \ --max-workers 4 \ --max-reqs-per-child 1000 \ --min-reqs-per-child 800 \ -E production \ -a app.psgi
13年11月20日水曜日
nginx.confupstream apps { #server localhost:5000; server unix:/tmp/app.sock;}
location / { proxy_set_header Host $host; proxy_pass http://apps;}
13年11月20日水曜日
benchmark
0
3000
6000
9000
12000 11534.51
7974.09
tcp unix
Kossy “Hello World” req/sec
13年11月20日水曜日
ISUCON本選では使ってない。。。
13年11月20日水曜日
ISUCON本選では使ってない。。。
TCPでListenしないからデバックしにくい試す時間がなかった
使ったとしても効果は限定的だったと思われる
13年11月20日水曜日
Plack/PSGIとパフォーマンスと私とまとめ
13年11月20日水曜日
普通のアプリケーション
アプリケーション側のコスト
>>>>> (超えられない壁) >>>>>
Plack/PSGIレイヤーのコスト
数十msec~数百msec
数msec~数百μsec
13年11月20日水曜日
特殊なアプリケーションeg: Games, advertisement, Large Scale SNS
アプリケーション側のコスト
>>>
Plack/PSGIレイヤーのコスト
数msec~数十msec
数msec~数百μsec
13年11月20日水曜日
Improve Plack/PSGI
• PSGI/Plackの適用領域を広げる= Perlの適用領域を広げる
• 大規模サービスでのコスト削減(Perlで働けるところ増えて、給料も増えてuma-)
13年11月20日水曜日
Found Problems?Github issues, pull reqs
IRC, @kazeburo
13年11月20日水曜日
#!n. thank you
13年11月20日水曜日