pixiv private isucon 2016 ��ά (1/5)
����������:
pixiv ���󤬼���dz��Ť����ץ饤�١��� ISUCON �� AMI ��������Ƥ��줿�Τǡ�����Ĥ��ʤ��鹶ά���Ƥ����ޤ���
- ISUCON6��������ब����ISUCON�򳫺š�AMI���������
- ��ݥ��ȥ�
���ε������о��ɼԤ�����Dz��򤹤�Ф������狼��ʤ��ʤäƤ��ޤ� ISUCON �鿴�ԤǤ��� Go �����Ѥ��ƹ�ά���Ƥ����ޤ�����¾�θ���ǻ��ä�����Ǥ�ͤ����ʤɤϻ��ͤˤʤ�Ȼפ��ޤ���
����¤ν������
ssh �θ����������줿�ꡢ���ǥ������� git �ʤɤΥġ�����򥤥󥹥ȡ��롦���ꤷ�ޤ���
���Τ�����ϻ����˼�ʬ�ѤΥ����ȥ����Ȥ䥹����ץȤ��äơ����᤯�Ǥ���褦�ˤ��Ƥ����ޤ��礦��
�ޥ���Ĵ��
���ڥå�
�Ȥꤢ���� CPU �ȥ��꤯�餤�Ϥ������İ����Ƥ����ޤ��礦��
$ grep processor /proc/cpuinfo processor : 0 processor : 1 $ free -m total used free shared buffers cached Mem: 998 906 92 12 25 335 -/+ buffers/cache: 545 453 Swap: 0 0 0
CPU��2�����Ǥ��͡�����ϥȡ�����1GB�ǥ���åפʤ��������դǤ���
ps aux
����ư���Ƥ��뤫��ǧ���ޤ��� �᡼�륵���С��Ȥ���AppArmor �Τ褦�ʡ����������餫�����פ����ʥǡ����ϡ��٥���ޡ�������������ꤵ���뤿��ȥ��������Τ������Ȥ��Ƥ������ۤ����ɤ��Ǥ���
������ä˲��⤹��ɬ�פϤ���ޤ���Ǥ�����
���ץ�λ����İ�
������֤�������������ǧ���Ƥ��顢�ºݤ˥��ץ��֥饦�����餵��äƤߤޤ��礦��
������֤ؤ������ϡ� tar �ǥ��������֤��ƥ�������˻��äƤ��Ƥ������ꡢ mysqldump ���ä��ꤷ�Ƥ������ɤ��Ǥ���
����������ξ���AMI������ľ����Τǡ� /initialize
�Ȥ����ѥ��ǽ���������ȸ������Ȥ������ץ�Υ����ɤdz�ǧ�����Хå����åפϼ�ȴ�����ޤ�����
ISUCON ���֤ǤϽ�����֤���������Τ�ɬ�פʥǡ����򥪥ڥߥ��Ǽ�����¨�ह�붲�줬����Τ����դ��ޤ��礦��
�֥饦���ΥǥХå���ǽ�Ǥɤ������̿��򤷤Ƥ���Τ������ꡢ���ץ�Υ����ɤ�URL�롼�ƥ�����ʬ���濴�˷ڤ��ܤ��̤����ꡢ mysqldump --no-data isuconp
�Ǽ��������������ޤ򻲹ͤˡ����ä�������������İ����Ƥ����ޤ���
nginx �������
��������������������Ѱդ��Ƥ������ե����ޥåȤ��ѹ����ơ� upstream �ؤ� keepalive
���դ��롣
���������ʤ��Τ� worker_processes
�� 1 �ˤ��ơ� keepalive
�θ�Ψ��夲�롣
��Ū�ե������ nginx �����֤�����ϡ����ץ��ư����İ����Ƥ���Ǥ��٤��ʤ��� Go �ʳ���Ȥ��ͤϡ���������Ū�ʥե����뤬ʬ���ä��ʳ��Ǥ����ˡ�Go ��Ȥ��ͤϤ������٥��塼�˥󥰤��ʤ�� nginx �򳰤����ɤ�����Ƚ�Ǥ��륿���ߥ󥰤� nginx �����֤��褦�ˤ��褦��
/etc/nginx/nginx.conf
:
worker_processes 1; ... ## # Logging Settings ## log_format isucon '$time_local $msec\t$status\treqtime:$request_time\t' 'in:$request_length\tout:$bytes_sent\trequest:$request\t' 'acceptencoding:$http_accept_encoding\treferer:$http_referer\t' 'ua:$http_user_agent'; access_log /var/log/nginx/access.log isucon;
/etc/nginx/sites-enabled/isucon.conf
:
upstream app { server 127.0.0.1:8080; keepalive 32; } server { listen 80; client_max_body_size 10m; root /home/isucon/private_isu/webapp/public/; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://app; } }
���ȡ������ Go ��Ȥ��Τ� ruby �� php �Υ����ӥ���ߤ�Ƥ��ޤ��ޤ��� Go �Υ����ӥ��ϳ�ȯ��ϥ��ޥ�ɥ饤��ǵ�ư�������ΤǤ����Ǥ����ꤷ�ޤ���
$ sudo systemctl stop isu-ruby $ sudo systemctl disable isu-ruby $ sudo systemctl stop php7.0-fpm $ sudo systemctl disable php7.0-fpm
MySQL �������
/etc/mysql/my.cnf
�򸫤Ƥߤޤ����ۤܥǥ����ȥ�Υǥե���ȤǻȤäƤ���褦�ʤΤǡ���������̺︺��IO�Ԥ��︺�Τ���˼�����������ɲä��Ƥ����ޤ���
innodb_flush_method = O_DIRECT innodb_flush_log_at_trx_commit = 2
�Ť����������᤯���Ĥ��뤿��Υġ�����Ѱդ��롣�ͤξ��� myprofiler ��Ȥ���
$ wget https://github.com/KLab/myprofiler/releases/download/0.1/myprofiler.linux_amd64.tar.gz $ tar xf myprofiler.linux_amd64.tar.gz $ sudo mv myprofiler /usr/local/bin/
myprofiler �λȤ����ϡ� myprofiler -user=root
�Ǥ��������꤬���äƤ����� myprofiler -user=root -interval=0.2
���餤�˥���ץ�󥰴ֳ֤�û��������ɤ��Ǥ��礦������ʳ��Υ��ץ����� myprofiler -h
�dz�ǧ���Ƥ���������
�٥���ޡ����μ¹ԤȤ��ä�������İ�
������:
{"pass":true,"score":4745,"success":4408,"fail":0,"messages":[]}
top:
Tasks: 81 total, 1 running, 80 sleeping, 0 stopped, 0 zombie %Cpu(s): 94.1 us, 4.2 sy, 0.0 ni, 0.3 id, 0.0 wa, 0.0 hi, 1.3 si, 0.0 st KiB Mem: 1022972 total, 701036 used, 321936 free, 21396 buffers KiB Swap: 0 total, 0 used, 0 free. 346564 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 720 mysql 20 0 1087768 140276 10724 S 142.8 13.7 0:52.09 mysqld 2908 isucon 20 0 582876 124364 8800 S 46.6 12.2 0:12.98 app 2904 www-data 20 0 91680 4800 2988 S 1.7 0.5 0:00.61 nginx
MySQL �� app ��3��CPU���äƤ�Τ��狼��ޤ���
myprofiler:
198 SELECT * FROM `comments` WHERE `post_id` = N ORDER BY `created_at` DESC LIMIT N 124 SELECT COUNT(*) AS `count` FROM `comments` WHERE `post_id` = N 11 SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` ORDER BY `created_at` DESC 9 SELECT * FROM `comments` WHERE `post_id` = N ORDER BY `created_at` DESC 5 SELECT * FROM `posts` WHERE `id` = N 4 SELECT COUNT(*) AS count FROM `comments` WHERE `post_id` IN (...N) 2 SELECT * FROM `users` WHERE `id` = ? 2 SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` WHERE `created_at` <= S ORDER BY `created_at` DESC 1 SELECT * FROM users WHERE account_name = S AND del_flg = N 1 SELECT COUNT(*) AS count FROM `comments` WHERE `user_id` = N
comments �� SELECT �� COUNT ���٤������狼�롣���μ��� posts �� select��
���ֺǽ�Υ��塼�˥�: ����ǥå���
���3��Υ�����ˤĤ��ơ�����ǥå�����Í�뤫��ǧ���ơ��ʤ����ĥ�äƤ�����
mysql> show create table comments\G *************************** 1. row *************************** Table: comments Create Table: CREATE TABLE `comments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `post_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `comment` text NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=100049 DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec) mysql> show create table posts\G *************************** 1. row *************************** Table: posts Create Table: CREATE TABLE `posts` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `mime` varchar(64) NOT NULL, `imgdata` mediumblob NOT NULL, `body` text NOT NULL, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10056 DEFAULT CHARSET=utf8mb4 1 row in set (0.00 sec)
comments.post_id
�� posts.created_at
�˥���ǥå������ʤ����Ť���������3�Ĥ����졣
mysql> create index post_id on comments (post_id); Query OK, 0 rows affected (0.19 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> create index created_at on posts (created_at); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0
�Ȥꤢ��������Ǥ⤦���ٷ�¬���Ƥ����ޤ���
top:
top - 18:13:32 up 2:13, 1 user, load average: 2.01, 0.84, 0.52 Tasks: 79 total, 1 running, 78 sleeping, 0 stopped, 0 zombie %Cpu(s): 74.0 us, 19.3 sy, 0.0 ni, 3.2 id, 0.2 wa, 0.0 hi, 3.4 si, 0.0 st KiB Mem: 1022972 total, 944288 used, 78684 free, 23344 buffers KiB Swap: 0 total, 0 used, 0 free. 462656 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2908 isucon 20 0 640148 174444 8800 S 109.7 17.1 0:44.93 app 720 mysql 20 0 1093212 212252 10740 S 58.5 20.7 1:56.57 mysqld
app �� mysql �� 2�ܤˤʤꡢ�����꤬�ͥå�����ʤ��ʤä��Τ��狼��ޤ���
������:
{"pass":true,"score":14208,"success":13157,"fail":0,"messages":[]}
myprofiler:
36 SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` ORDER BY `created_at` DESC 15 SELECT COUNT(*) AS count FROM `comments` WHERE `user_id` = N 5 SELECT * FROM `comments` WHERE `post_id` = N ORDER BY `created_at` DESC LIMIT N 4 SELECT `id`, `user_id`, `body`, `mime`, `created_at` FROM `posts` WHERE `created_at` <= S ORDER BY `created_at` DESC
���2��򸫤��
posts
����� SELECT �� LIMIT ��̵��comments.user_id
�˥���ǥå������ʤ�
LIMIT ���ʤ��Τϥ��ץ�¦�ǽ�����ɬ�פʤΤȡ��ܥȥ�ͥå������ץ�˰ܤäƤ�Τǡ����ץ�����˰ܤ롣
comments.user_id
�ϤĤ��Ǥ˥���ǥå���ĥ�äƤ�������1�ֽŤ������ꤸ��ʤ��Τǥ٥���Ͼ�ά��
mysql> create index user_id on comments (user_id); Query OK, 0 rows affected (0.14 sec) Records: 0 Duplicates: 0 Warnings: 0
�ޤȤ�
������: 4745 (�������) -> 14208 (����ǥå������塼�˥�)
systemd �Υ��ޥ�ɤȤ� nginx ������Ȥ� MySQL ������ե�����򸫤�Ȥ�����ǥå���ĥ��Ȥ�������������ơ������ޤǤϥ��ࡼ���ˤǤ���褦�ˤʤ�ޤ��礦��
�����ͤǤ�������ͤǤ�äƤ���Ϥ����ޤǤ�2���ְ���ˤϽ���餻����褦�ˤ��ޤ��礦��1���֤��ڤ��Х������Ǥ���
@methane