2016ǯ05��30��

pixiv private isucon 2016 ��ά (1/5)

¤Ï¤Æ¤Ê¥Ö¥Ã¥¯¥Þ¡¼¥¯¤ËÅÐÏ¿

����������:

pixiv ���󤬼���dz��Ť����ץ饤�١��� 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

songofacandy at 11:09��Comments(0)��TrackBack(0)��ISUCON | golang

�ȥ�å��Хå�URL

���ε����˥����Ȥ���

̾��:
URL:
  ����òµ­²ï¿½: ɾ��: ��    ��
 
 
 
Blog�⸡��
�ǿ�����
Archives
���Υ֥����ˤĤ���
DSAS�Ȥϡ�KLab �����ۤ����Ѥ��Ƥ��륳��ƥ�ĥ����ӥ��Ѥ�Linux�١����Υ���ե�Ǥ�������5����Υǡ������󥿤ˤƹ��ۤ������Ѥ��Ƥ��ޤ������桹��DSAS����Ȥ��䤹�����������ˡ������Ƥ����ϤDZ��ѤǤ��뤳�Ȥ��ܻؤ��ơ��������ɤ˶Ф���Ǥ��ޤ���
���Υ֥����Ǥϡ������ DSAS �ǻȤäƤ��뵻�ѤξҲ�䡢�¸����Ƥߤ���̤���𡢥ȥ�֥�˴������ޤ줿���ηи��̤ʤɡ���������������������򿥤�ޤ��ƾҲ𤷤Ƥ��������Ȼפ��ޤ���
�ǿ�������
<%==comments[n].author%>
<% } %>