ãã®ããã°ã¯ç§»è»¢ãã¾ãã
ä¸è¨ã«ç§»è»¢ãã¾ããã
ISUCON8äºé¸1æ¥ç®ã«ãã¼ã ãSELinuxã¯Enforcing以å¤ããå¾ãªããã§åå ãã¦æçµã¹ã³ã¢ã¯26,221ã§ãã
ãã¯ããã®ããã°ã¯ISUCONåå è¨ã«æãä¸ãã£ã¦ãã¾ã£ã¦ã¾ããã
ä»å¹´ã@ishikawa84g ã@netmarkjpã@matsuuã®3人ã§ISUCON8ã«æãã§ãã¾ããããã®ã¹ã³ã¢ããä»å¹´ãæ¬é¸é²åºã¯é£ãããã§ããããã£ããã
ãã¼ã åã®ã¨ãããDisabledã ã£ãSELinuxã¯Enforcingã«ãã¦ãã£ããã·ã¥ã§ãã
ãã£ããã¨
3人ã§ä½æ¥åæ ããã¦ãã®ã§ãåºæ¬çã«èªåããã£ããã¨ãã¾ã¨ãã¾ã
- ãã³ãåã®æºåã¹ã¯ãªããã¨ãã³ãå¾ã®éè¨ã¹ã¯ãªãã(kataribe, pt-query-digest)ãç¨æ
- getEventå ã®N+1ããã£ã¤ãã
- ORDER BY RAND()ãæ¶ãã¦ã¿ããã®ã®ã©ã³ãã ãããªãã¨æãããã®ã§å·®ãæ»ã
- sheetsã¯å¢æ¸ããªãä¸ã«sheet_idããç®åºã§ããã®ã§ãã§ããã ãå©ç¨ããªãããã«å®è£ å¤æ´(sheetsã²ã£ãºãã)
- /api/users/:id ã®N+1ããã£ã¤ãã
- æ®å¸æ°(remain)ã¯eventsã«ã«ã©ã ã追å ãã¦æ ¼ç´ããããã«å¤æ´ãããã®ã®ããããããã¯ãçºçããã®ã§remainsãã¼ãã«ãå¥éä½æãã¦æ ¼ç´ããããã«ï¼ãããæçµçã«failã«ãªãã®ã§å·®ãæ»ãï¼
- /api/events/:id/actions/reserve å ã® ORDER BY RAND() ããããªãããã«å ¨sheetã«ä¹±æ°ã®ã«ã©ã ã¨ã¤ã³ããã¯ã¹ã追å ãã¦ã½ã¼ãããããã«ï¼ãããæçµçã«failã«ãªãã®ã§å·®ãæ»ãï¼
- 1å°ç®ã®h2oã¨webappã¨mariadbã¯ãã®ã¾ã¾ã2å°ç®ã¨3å°ç®ã«webappã稼åããã/initializeã®ã¢ã¯ã»ã¹ä»¥å¤ã¯2å°ç®ã¨3å°ç®ã«æ¯ãããã«å®è£ å¤æ´ï¼ãããæçµçã«failã«ãªãã®ã§å·®ãæ»ãï¼
ã¾ã¨ã
ä¸è¨ã¹ã¯ãªã¼ã³ã·ã§ããã«ãããã¨ãããç´åã§ãsuccess/failãã¦ãããªããªãå³ããå
容ã§ããã
ä»åã¯ãã©ã³ã¶ã¯ã·ã§ã³ããã¡ãã¨æèããä¸ã§æ¹ä¿®ã§ããããèã ã£ãã¨ã®èªèãªã®ã§ãããããç¨åº¦æ§è½ãä¸ãã£ã¦ããã¨failãçºçãã¦ãã¾ããçµå±å¤ãã³ãããã«ã¾ã§å·®ãæ»ãã¦ï¼ããã§ããã¾ã«failãåºãï¼ç¡é£ãªã¹ã³ã¢ã§ãã£ããã·ã¥ããããå¾ãªãè¦ããå±éã§ãããã¤ããã
èªåã§å¤æ´ããå®è£ ã«åé¡ããã£ãå¯è½æ§ã9å²ä»¥ä¸ããã®ã§ãããããããããGoå®è£ ã§getEventså ã®getEventå¼ã³åºããåä¸ãã©ã³ã¶ã¯ã·ã§ã³ã«ãªã£ã¦ããªãã£ãã®ããã種ã®ç½ ã«ãªã£ã¦ããã®ã§ã¯ãªããã¨èãã¦ãã¾ããããããããgetEventsã®N+1ãéæ²»ããã°çµæã¨ãã¦è§£æ¶ããã®ã§ã¯ã¨æãã¨ããã¼ãæãããåé¡ãå ¬éãããã追試ãããã¨æãã¾ãã
æãæãå®è£ ã«ããããã£ãããã³ããã¼ã«ã¼ãæ¤ç¥ãã¦ã¦ã ã ã ãããªãã¨æããå¸ãè¯ãå®è£ ã ã£ãã¨æãã¾ãããã¹ã¦ã®ãµã¼ãã¼ãµã¤ãããã°ã©ãã¼ã¯ãã©ã³ã¶ã¯ã·ã§ã³å¦çã¨ã¯ã©ããããã¨ãã¨ããã®ãå¦ã¶è¯ãææã«ãªãã®ã§ã¯ãªãã§ãããããã¿ããªéå»åããããªã
ISUCON7äºé¸1æ¥ç®ã«ãã¼ã ãããã¦ãã§åå ãã¦æçµã¹ã³ã¢ã¯205148ã§ãã
Webãµã¼ãã¹ãããæãã«ããã©ã¼ãã³ã¹ãã¥ã¼ãã³ã°ããã³ã³ãã¹ã
ISUCON7äºé¸1æ¥ç®ã« @netmarkjp, @ishikawa84g, @matsuu ã§ãã¼ã ãããã¦ãã«ã¨ãã¦åå ãã¾ãããæçµã¹ã³ã¢ã¯ 205148 ã§ããã
èå¯
netmarkjp
- ä¾å¹´éãã®å½¹å²åæ ããã£ããæ©è½ãã¦æ°æã¡ããã§ãã
- è¦ç¹ãå¤ãããä¼æ©ã¨ã£ãããããæãã«ã§ãã
- å»å¹´ã®ä½ãã§ããªãã£ãç¡å¿µã¯å¤å°ä¾é¤ã§ãã
- ç·´ç¿ããã¡ãã¨æ´»ããã
- ãã³ããå®å®ãã¦ã¦ãããããã£ã
- BGMã¯æ±äº¬ã¹ã«ãã©ãã¤ã¹ãªã¼ã±ã¹ãã©ã§ãã
matsuu
- ãã©ãã£ãã¯ãããã«ããã¯ã«ãªãåé¡ããªããªã解決ã§ããã«ããããCache-Controlã«publicãå ¥ãããã¨ãæãã¤ãã
- 304å¿çãå®å®ãã¦çºçããªãçç±ãçæãããç»åã®æ´æ°æ¥æããµã¼ãæ¯ã«ç°ãªãããã§ãããã¨ã«æ°ã¥ããèªåãè¤ãã¦ãããã
- tcpdumpã§ãã³ããã¼ã¯ã®ãã©ãã£ãã¯ãtcpdumpãã¦ã¿ãã®ã大ããã£ã
- Pixiv社å ISUCONã使ã£ã¦ãã£ãããã¥ã¼ãã³ã°ããã¨ãã®çµé¨ãã¨ã¦ãå½¹ã«ç«ã£ãããããã¨ãPixiv
- Discordãã£ãããçµæ§ããã£ããã²ã¼ã ãããªãã¦ããããã£ãã¤ãã³ãã«ã¨ã¦ãåãã¦ããã¨æãã®ã§ãªã¹ã¹ã¡
- NEW GAME!!ãåãã¦è¦ããã¨ã³ã¸ãã¢ããããã§ã°ãã¨ããããªãã»ã©ã
ishikawa84g
- Microsoft Wireless Display Adapter ã¯ä¾¿å©ã
- ãã ãã6æéãããé£ç¶ç¨¼åããã¨ãã³ã°ãããã¨ãããããã§ãããã°ããå¯ãããã¨å¾©æ´»ããã
- éå§æéã伸ã³ã¦ãããæ
ã¦ããªã©ãã¯ã¹ãã¦éå§ã§æ¥ãã(æµç³ã¿ããªãã©ãã«æ
£ããã¦ãããï¼)
- Discordã§ãããããããNEW GAME!ã¯3話ã¾ã§è¦ã¾ããã
- 常ã«ç·å¼µç¶æ ããå¿ è¦ã¯ãªããç· ããã¨ãããç· ããã°åé¡ãªãï¼
- Discordã®ã³ãã³ãã«FF14ã®Wikiãæ¤ç´¢ããã¨ããã£ãã
æçµæ§æ
[nginx -- (varnish) -- gunicorn]x2 -- [mysql]x1
- å½åæ§æãããã¾ãå¤ãã
- ãã³ãå ã¯å é 2å°
- ãããã¯ã¼ã¯ããã«ããã¯ã®éã¯3å°ã«æ¯ã£ããã©ãçµå±DBãµã¼ãã®CPUã足ããæ»ãã
- æ稿ãããç»åã¯éçãã¡ã¤ã«ã¨ãã¦åºåããnginxã§éçãã¡ã¤ã«ãè¿å´
/icons/*
ã¯ãã¡ã¤ã«ã«åºåãåºæ¬çã«nginxããããªããã°varnishãçµç±ãã¦ã¢ããªã§ãã¡ã¤ã«çæ- ãã®ä»ã®ãã¹ã¸ã®ãªã¯ã¨ã¹ãã¯varnishãçµç±ããç´æ¥gunicornã¸
- varnishã¯
/icons/*
ã®Thunerding Herd対çã¨ãã¦å°å ¥ - ãã®ä»MySQLãnginxãã¢ããªã®ãã¥ã¼ãã³ã°ãå®æ½
äºåæºå
ãã¼ã å ä½å¶ã®æ§ç¯
- ãã£ããã¯Slackã§
- gitãªãã¸ããªã¯ Gitlab.com ã§
- 使ã£ããã¨ããªããã¼ã«ã使ã£ã¦ã¿ããã¨ãããã¨ã§ç°å¢æ§ç¯ã¯itamaeã§ãããã¸ã§ãã³ã°
- åææ§ç¯ä»¥éã¯çæ決æ¦ã®ããitamaeã§ç®¡çããªã
- git pushãã¼ã¹ã®CIãããã¸ã§ãã³ã°ã¯å®æ½ããªã
- äºåç·´ç¿ã§è©¦ãããã®ã®çæ決æ¦ã§ã¯ã©ããã£ã¦ãé ã
- ãµã¼ãã§ç´æ¥Vimã使ã£ã¦ç·¨é
- ä»ã®äººãç·¨éãã¦ãå ´åã¯
vim -R
ã§åç §
- ä»ã®äººãç·¨éãã¦ãå ´åã¯
ç°å¢æ§ç¯ç¨ã¬ã·ããç¨æ
itamaeã使ã£ã¦ä»¥ä¸ã®ãããã¸ã§ãã³ã°ãèªåå
- githubããSSHå ¬ééµãåå¾ãè¨å®
- 以ä¸ã®è§£æãã¼ã«ãã¤ã³ã¹ãã¼ã«
- dstat
- kataribe
- MySQLTuner
- netdata
- Percona Toolkit pt-query-digestã®ãã
- gprof2dot Pythonã®WSGIãããã¡ã¤ã©Werkzeugã®ã°ã©ãåãã¼ã«
- 以ä¸ã®ããã«ã¦ã§ã¢ãã¤ã³ã¹ãã¼ã«
- ãã³ããã¼ã¯ããããåã®åæåå¦ç/ãããå¾ã®è§£æå¦çãå®è¡ããã¹ã¯ãªãããç¨æ
- åæåå¦ç
- MySQLã¹ãã¼ã¯ã¨ãªã¼ãã°ãåé¤ãã¦
mysqladmin flush-logs
- nginxã®ã¢ã¯ã»ã¹ãã°ãåé¤ãã¦
systemctl reload nginx
- ã¢ããªãããã¡ã¤ã©ã®åºåãåé¤ãã¦ã¢ããªã±ã¼ã·ã§ã³ããã°ã©ã ã®åèµ·å
- MySQLã¹ãã¼ã¯ã¨ãªã¼ãã°ãåé¤ãã¦
- 解æå¦ç
- MySQLã¹ãã¼ã¯ã¨ãªã¼ã«å¯¾ãã¦
pt-query-digest
ãå®è¡ - MySQLTunerãå®è¡
- nginxã®ã¢ã¯ã»ã¹ãã°ã«å¯¾ãã¦
kataribe
ãå®è¡ - pythonãããã¡ã¤ã©Werkzeugã®åºåã«å¯¾ãã¦
gprof2dot
ã¨graphviz
ãå®è¡ãã¦ã°ã©ãçæ
- MySQLã¹ãã¼ã¯ã¨ãªã¼ã«å¯¾ãã¦
- åæåå¦ç
éå»åã解ãã¦äºè¡æ¼ç¿
äºåå ¬éã®ã¬ã®ã¥ã¬ã¼ã·ã§ã³ãçèª
大äº
å½æ¥ä½æ¥
9:00 - 10:00
éå
é»æºãæ¤
åãã¢ãã¿ã¼ã®è¨å¶ã¾ã§ãã£ã¦ããã¨ã¯ããã¿ãª
大äºãªã®ã¯æ¨ªä¸¦ã³ã«åº§ããã¨
11:30 æ¼é£
è½ã¡çãã¦ç¾å³ããæ¼é£ããã³ãã¼ã¬ã¼ç»åãåå è ãã£ããã«æä¸
12:00 - 13:00 â»éå§å
ISUCONåå è å°ç¨ãã£ããã§NEW GAME!!ã®è©±é¡ãçãä¸ãã£ãããAmazonビデオã§è¦è´éå§
13:00 éå§äºå®æå»
ãã¼ã¿ã«ãµã¤ãã...ãªã¼ãã³ããªã
13:10 éå¶ããDiscordã§ç·æ¥é£çµ¡
methane - ä»æ¥ åå¾1æ10å ããã¡ãã£ã¨ããããï¼
13:13 éå§
SSHæ¥ç¶ã§ããªããã©ãã«ã«è¦èããããã®ã®ããã®éã«ååãã³ããã¼ã¯å®è¡ã¨å½æ¥ã¬ã®ã¥ã¬ã¼ã·ã§ã³ãçèª
13:30 ãã°ã¤ã³å¾
äºãç¨æãã¦ããç°å¢æ§ç¯ã¬ã·ããå®è¡
並è¡ãã¦ãåãã·ã³ã®ã¹ããã¯ã¨ã使ããã¦ããããã«ã¦ã§ã¢ã確èª
ãµã¼ãã¹ã®ç»é¢ãè¦ããã³ã¼ããèªãã§ãã©ããªã¢ããªãªã®ããã£ããææ¡
ãã¼ã¿ã«ä¸ã§ãµã¼ããéé ã§ä¸¦ãã§ã¦ããå é 2å°ããã©ããªã®ãã¡ãã£ã¨æ··ä¹±ãã
MySQLã®ãã¥ã¼ãã³ã°ã§/dev/shmã«æ ¼ç´ãããã¨ããã¨ããAppArmorã«å¼ã£ããã£ããããAppArmorã調æ´
/etc/apparmor.d/usr.sbin.mysqld
ã«ä»¥ä¸ã追è¨
# ISUCON2017 /dev/shm/ r, /dev/shm/** rw, /proc/** r, /sys/devices/system/node/ r, /sys/devices/system/node/** r,
å¤æ´å¾ãProfileããªãã¼ãããMySQLãåèµ·åããã
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld sudo systemctl restart mysql.service
14:01 webappé ä¸ãgit管çã«
pythonã§å®è£ ããæ¹éã«ãããããpublicãã£ã¬ã¯ããªã¨pythonãã£ã¬ã¯ããªãgitã«çªã£è¾¼ã¿commit
14:08 ã¤ã³ããã¯ã¹è¿½å
ã¹ãã¼ã¯ã¨ãªã¼ããé ããªã¯ã¨ã¹ãã調ã¹ã¦ã¤ã³ããã¯ã¹è¿½å
ALTER TABLE image ADD INDEX (name); ALTER TABLE message ADD INDEX (channel_id);
14:30
ä¸ç¬ã ã1ä½ç²å¾
https://twitter.com/matsuu/status/921609614881202178
netdataè¦ãã®ã¯ãã®é ã¾ã§ã§ããã¨ã¯dstatã¨top
tmuxã§3å°å並ã¹ã¦è¡¨ç¤ºãæä½ã¯tmuxã®synchronized-paneã§æ¥½ã å®æ½
14:33 /icons/ã®éçãã¡ã¤ã«å
DBã«æ ¼ç´ããã¦ããç»åãã¼ã¿ãéçãã¡ã¤ã«ã¨ãã¦åºåããå®è£ ãè¡ã
def get_images(): cur = dbh().cursor() cur.execute("SELECT name, data FROM image") for row in cur.fetchall(): output = "/home/isucon/images/{}".format(row['name']) with open(output, 'wb') as file: file.write(row['data'])
åºåããç»åã¯nginxããç´æ¥å¿çããããã«å¤æ´
location /icons/ { expires 60s; alias /home/isucon/images/; try_files $uri @upstream; } location @upstream { proxy_set_header Host $http_host; proxy_pass http://127.0.0.1:5000; }
14:34é DBã¨ã¢ããªéã®ãã©ãã£ãã¯æ¹å
dstatã§è¦ã¦ããã¨DBã¨WEBã®éã®ãã©ãã£ãã¯ãå¤ãã®ã«ãã³ããã¼ã«ã¼ã¨WEBã®éã®ãã©ãã£ãã¯ãå°ãªããã¨ã«æ°ã¥ãã
åãå 容ã®ç»åãåããã¡ã¤ã«åã§éè¤ç»é²ããã¦ããç¡é§ã«DBããã®åå¾ãçºçãã¦ãããã¨ã«æ°ã¥ããã®ã§1è¡ã ãåå¾ããããä¿®æ£
cur.execute("SELECT * FROM image WHERE name = %s", (file_name,)) cur.execute("SELECT * FROM image WHERE name = %s LIMIT 1", (file_name,))
14:57 éçãã¡ã¤ã«ã®gzip_staticå
éçãã¡ã¤ã«ãäºãgzipãã¦ä¿åãã¦ãããnginxã® gzip_static
ã§å¿çããããã«
gzip_static on; gzip_types image/svg+xml text/css text/javascript application/javascript application/font-wof f application/vnd.ms-fontobject;
15:21é ç»åãçæãã
ç»åãINSERTæãSELECTæã«åºåããããå¤æ´ã
ããããµã¼ããã¨ã«ç»åãçæããå®è£
ã®ãããã®å¾ãã°ããã¹ã³ã¢ã伸ã³æ©ã
- ç»åã«expiresãä»ãã¦ã¿ãâå¤å°æ¹åãããã®ã®æ ¹æ¬è§£æ±ºã«ã¯ãªãã
- /fetchã®1ç§å¾ æ©ãå¤ãã¦ã¿ãâå¹æãªã
- 206ã¬ã¹ãã³ã¹ãè¿ãã¦Rangeãããã¼ã§è¿ãã°ããã®ã§ã¯ï¼â206å¿çãç°¡åã«å®è£ ããæ¹æ³ããããã
- limit_rateã§ä»£ç¨ãããã¿ã¤ã ã¢ã¦ã
- 302ãªãã¤ã¬ã¯ãã§å¿çãé ãããã°ããï¼â302ãªãã¤ã¬ã¯ãã¯ã¨ã©ã¼ã«ãªã£ã
17:24é /fetchã®ãã¥ã¼ãã³ã°
SQLãè¦ç´ãã¦N+1ã解æ¶
SELECT channel.id AS channel_id, CASE WHEN message_id IS NULL THEN (SELECT COUNT(*) FROM message WHERE channel_id = channel.id) ELSE (SELECT COUNT(*) FROM message WHERE channel_id = channel.id AND message_id < id) END AS unread FROM channel LEFT JOIN haveread ON channel.id = haveread.channel_id AND user_id = ?
18:17é ç»åãã¡ã¤ã«çææã«æ´æ°æ¥æãåããã
ãã³ããã¼ã¯ããã®HTTPãªã¯ã¨ã¹ããtcpdumpã§è¨é²ãã¦ã©ã®ãããªãªã¯ã¨ã¹ããå±ãã¦ãã確èªãã¦ã¿ã
tcpdump -w dump tcp port 80
ãã®çµæãWiresharkã«é£ããã¦ç¢ºèªãã¦ããã¨ãããIf-Modified-Sinceãããã¼ãè¦ã¤ãã¦æãã¤ããã
ãç»åãã¡ã¤ã«ã®æ´æ°æ¥æãåããã¦ãªããã304å¿çãè¿ãã¦ããªãã®ã ãã¨ãã¨ã¦ã¬ã«ï¼
def write_image(data, name): output = "/home/isucon/images/{}".format(name) with open(output, 'wb') as file: file.write(data) os.utime(output, (1508559193, 1508559193))
1508559193
㯠2017/10/21 13:13:13
ãISUCON7äºé¸1æ¥ç®ã®éå§æ¥æã
18:33
帯åãå¤å°ãã·ã«ãªã£ãã®ã§webãµã¼ãã®CPUè² è·ãä¸ããããã« gzip off
18:51é /messageã®ãã¥ã¼ãã³ã°
SQLãè¦ç´ãã¦N+1ã解æ¶
if last_message_id > 0: cur.execute("SELECT message.id, name, display_name, avatar_icon, message.created_at, content FROM message JOIN user ON message.user_id = user.id WHERE message.id > %s AND channel_id = %s ORDER BY message.id DESC LIMIT 100", (last_message_id, channel_id)) else: cur.execute("SELECT message.id, name, display_name, avatar_icon, message.created_at, content FROM message JOIN user ON message.user_id = user.id WHERE channel_id = %s ORDER BY message.id DESC LIMIT 100", (channel_id, ))
19:00é ç»åãã¡ã¤ã«çææã®åºåå ã/dev/shm/ã«ãã
with tempfile.TemporaryFile(dir="/dev/shm/") as f:
19:10 Pythonãããã¡ã¤ã©Werkzeugã®å°å ¥
æã¤æãå°ãªããªã£ã¦ããã®ã§Werkzeugã§ã®ãããã¡ã¤ã«ãå®æ½ã
from werkzeug.contrib.profiler import ProfilerMiddleware app.wsgi_app = ProfilerMiddleware(app.wsgi_app, profile_dir="/tmp/profile")
gprof2dotã使ã£ã¦dotãã¡ã¤ã«ãçæããgraphvizã使ã£ã¦pngãã¡ã¤ã«ãçæã
gprof2dot -f pstats --colour-nodes-by-selftime --show-samples /tmp/profile/* > profile.dot dot -Tpng profile.dot > profile.png
19:48é rapidjsonã®å°å ¥
Werkzeugã«ãããããã¡ã¤ã«ã®çµæãJSONçæã«æéãããã£ã¦ãããã¨ãå¤æãããããflask.jsonify()ãrapidjsonã«å·®ãæ¿ãã
20:15é WSGIãµã¼ããmeinheldã«å·®ãæ¿ãâå·®ãæ»ã
WSGIãµã¼ããgunicornããmeinheldã¸å·®ãæ¿ãã¦ã¿ããã®ã®å¤§å¹ ã«æ§è½ãä¸ããæ念ã
20:27
sleep対å¿ã§gunicornã®ã¯ã¼ã«ã¼ãæ¸ããã¦ã¹ã¬ãããå¤§å¹ ã«UP
/etc/systemd/system/isubata.python.service
ã§--workers=1 --threads=1000
ã¨è¨å®
20:31 MySQLãã©ã¡ã¼ã¿èª¿æ´
ã¢ããªå´ã§ Too many connections
ãåºã¦ããã®ã§MySQLè¨å®å¤æ´
max_connections = 8192
㨠open_files_limit ãè¨å®- /lib/systemd/system/mysql.service ã«
LimitNOFILE=65535
ã追è¨
20:35é ãã³ãã¬ã¼ãã¨ã³ã¸ã³Jinja2ã®ãã¥ã¼ãã³ã°
jinja2ã®bytecode_cacheãæå¹ã«
app.jinja_options = app.jinja_options.copy()
app.jinja_options['bytecode_cache'] = jinja2.FileSystemBytecodeCache()
20:49 ç»åãã¼ã¿ã®è¨ç½®å¨ããä¿®æ£
ã¢ãããã¼ããããç»åãtmpãã¡ã¤ã«ã«åºåããéã«æçµçãªè¨ç½®å ´æã«ãã¼ããªã³ã¯
os.link(f.name, output)
20:50éã åèµ·åãã¹ã
åèµ·åãã¹ãå®æ½
åèµ·åå¾ã«ãã³ãå®è¡ãããã¹ã³ã¢ãä¹±é«ä¸ããã®ã§ããæãã«ãªãã¾ã§ç¹°ãè¿ããã³ãå®è¡
ä¸è² è·å´ãå®å®ãã¦ã¦é«éã§å©ãã£ã
21:07ããã¹ãã¹ã³ã¢ãã§ãã¾ã§ãã³ããã¼ã¯ãç¹°ãè¿ã
æ¬æ¥ã®ãã¹ãã¹ã³ã¢ 205148
ãåºã¦æ声
21:13 çµäº
ãç²ãæ§ã§ããã
æ¸ç±ãLinuxã¹ãããã¢ããã©ã¼ãã³ã°ã
èè ã§ãã @ryosuke927 ãããããæµè´ã«ä¸ãã¾ãããæè¬ã
Linuxã¹ãããã¢ããã©ã¼ãã³ã°
- ä½è : æ²åäº®å ¸
- åºç社/ã¡ã¼ã«ã¼: æè¡è©è«ç¤¾
- çºå£²æ¥: 2017/04/11
- ã¡ãã£ã¢: 大åæ¬
- ãã®ååãå«ãããã°ãè¦ã
Ubuntu 16.04 LTSããã¼ã¹ã«Linuxã®åºæ¬æä½ãå¦ã¹ãåå¿è
åãæ¸ç±ã§ããããã®æ¬ã®ç´ æ´ãããã¨ããã¯ã»ã¼ãã¹ã¦ã·ã§ã«ã§ã®æä½æ¹æ³ãã¾ã¨ãä¸ãã¦ãã¨ãããç¾å ´ä¸»ç¾©ã®ä¸åã¨ãã¦ç´ æ´ãããã
ç°å¢æ§ç¯ã¨ãã¦VirtualBoxãç´¹ä»ããã®ãçã«ããªã£ã¦ããã§ãããããã©ã¤ããªã©æ¬çã¨ã¯ç°ãªãé¨åã§èºãã®ã¯å®ã«ãã£ãããªãã®ã§ç¾å®çã§è¯ãã¨æãã¾ãã
ãã ããã®æ¸ç±ã®1ã¤æ®å¿µãªã¨ããã¯ãpp.12-13ã®ã主ãªLinuxãã£ã¹ããªãã¥ã¼ã·ã§ã³ãã«Gentooããªãã¨ããã§ããããã¸ããä»ãChromebook*1ãDockerãã¹ã*2ãPepperå*3ãªã©ã§ä¸çãå¸å·»ãã¤ã¤ããGentooç³»OSãç´¹ä»ãããªããªãã¦ãç§ã¯æ²ããã
4/11çºå£²ã§ããå£ç¯æãæ°äººæè²ã«ãæé©ã ã¨æãã¾ããæ¯éã¨ããæ¤è¨ãã ããã
ISUCON6æ¬é¸ã§åèªéå¶ã¨ãã¦ãæä¼ããã¦ãã¾ãã
@matsuu #isucon ãååããã ãèª ã«ãããã¨ããããã¾ããï¼ãã¼ã ã¨ãã¦ã¯æ®å¿µãªçµæã¨ãªãã¾ããããäºé¸ã«ããã¦å¤å¤§ãªããå°½åãããã ãã¾ããã®ã§matsuuãããåèªéå¶ã¨ãã¦æ¬é¸ã«ãæå¾ ãããã¨æãã¾ãï¼æ¬é¸åºå ´ã§ã¯ãªãéå¶ã¨ãã¦ã®åå ã§ãï¼ãæ¤è¨ãã ããã¾ã
— ISUCONå ¬å¼ (@isucon_official) 2016å¹´9æ18æ¥
ãã®è©±ãé ããæã¯æ£ç´ãåèªéå¶ã¨ã¯ãã¨æã£ãã®ã§ãããæ¬é¸ã«é²ãã¤ããã§äºå®ãéãã¦ããã¨äºã¤è¿äºã§å¼ãåãããã¨ã«ãã¾ããã
æ¬é¸éå¶ã®ãæä¼ãã¨ãã¦ãã£ããã¨ã¯ä»¥ä¸ã®ã¨ããã
Azureé¢é£
Azureã®ç¹æ§ãè¸ã¾ããä¸ã§ã®æ§ææ¤è¨ãã¯ã³ã¯ãªãã¯ãããã¤ã®ããã®ãã³ãã¬ã¼ãä½æãªã©ãè¡ãã¾ããã
äºé¸ã§ã¯ãããã¤ã®ä»çµã¿ã«customData使ããã¦ãã¾ããããcustomDataã¯å®è¡ã¹ã¯ãªãããbase64ã«å¤æããå¿
è¦ããããå¤æ´ã®ãã³ã«æéããããã®ã§ãカスタムスクリプト拡張機能ãç¨ãã¦ãããã¤ãããã¨ã«ãã¾ããã
customDataã¯Ubuntuãªã©ä¸é¨ã®Linuxã§ããåä½ããªããããã«ã¹ã¿ã ã¹ã¯ãªããæ¡å¼µãå©ç¨ããã®ããªã¹ã¹ã¡ã§ãã
ã¾ãããã£ããã ããAzureã®ãµã¼ãã¹ãæå¹æ´»ç¨ãããã¨ã®æµããããAzureã®Log Analyticsãç¨ãã¦ç«¶æè ã®åãµã¼ãã«メトリックス情報を収集する拡張機能ãã¤ã³ã¹ãã¼ã«ããããã«ãã¾ããã
ISUCONç¨ã®azureã¤ã³ã¹ã¿ã³ã¹ã§OMS Agent(==fluentd)ãåãã¦ããâ¦â¦ï¼
— tagomoris (@tagomoris) 2016å¹´10æ22æ¥
ãããããããã§ãå®ã¯ç§ã®ãã¹ã§OMSå´ããã¾ãåããªãã£ããã§ããã©ãâ¦ã
CIã®æ§ç¯
æ¬é¸ã®æºåã¯GitHubã®ãã©ã¤ãã¼ããªãã¸ããªã§é²ãã¦ããã®ã§ãããAzureã®ã¯ã³ã¯ãªãã¯ãããã¤ãå®ç¾ããããã«ã¯å
¬éé åã«ãã³ãã¬ã¼ããç½®ãå¿
è¦ããããã¨ã¨ããããã¤ç¨ã®ãã¡ã¤ã«ä¸å¼ãåºãããã¡ã¤ã«ãçæããå¿
è¦ããã£ããããCIç°å¢ãä½æãã¾ããã
CIãµã¼ãã¹ã¯ãã©ã¤ãã¼ããªãã¸ããªã§ãç¡æã§ä½¿ããWerckerãæ¡ç¨ãã¾ããã
ã¾ããä»åã®æ¬é¸ã¯Dockerç°å¢ã ã£ãã®ã§ãããDockerã®ãã«ãããã³åä½ãã¹ããè¡ãããã«å¥éJenkinsãµã¼ããç¨æãã¾ãããDockerã®ãã¹ãã«Werckerã使ç¨ããªãã£ãã®ã¯ãç¾ç¶Dockerのビルド環境としてWerckerは使えないããã§ã*1ã
Pythonå®è£
æ¬é¸ã®Pythonå®è£
ã¯ç§ãæ
å½ããã¦ããã ãã¾ããã
ç§ãæ¬è·ããã°ã©ãã¼ã ã£ãé ã¯ä¸»ã«Perl/PHPãçæ¥ã¨ãã¦ãããã¤ã³ãã©ã¨ã³ã¸ãã¢ãªä»ã¯ã¡ãã£ã¨ãããã¼ã«ä½æã«Pythonãæ¸ããã¨ãå¤ããã®ã®Pythonã§Webã¢ããªã±ã¼ã·ã§ã³ãå®è£
ããçµé¨ã¯ã»ã¼ã¼ããã¨ã¦ãä¸å®ã§ããããªãã¨ãå®è£
ãããã¨ãã§ãã¾ããã
å½åã¯Twistedãã¼ã¹ã®å®è£
ãä¾é ¼ãããã®ã§ãããçæãã¦ã¿ãã¨ããèªåã®åéã§ã¯ç¡çã ã¨å¤æããFlaskã§å®è£
ããªããã¦ãã¾ãã
ã¾ããPython3+Gunicorn(sync)ã ã¨Server Side Eventsã®å®è£
ã§yieldå¨ãããã¾ãåãããã®ãªã®ãªã«ãªã£ã¦æ¥é½Python2+Gunicornã«ç½®ãæããããã¾ããã
æ®å¿µãªããPythonで予選を通過したチームはいなかったãããªã®ã§èª°ããã試ããã¦ããªãå¯è½æ§ãããã¾ããããè¯ãã£ããPythonå®è£
ã§åé¡ã解ãã¦ã¿ã¦ãã ãããã
èªåã®ç¥è¦ã«åºã¥ãã¢ããã¤ã¹
ãã®ä»ãèªåã®ç¥è¦ã«åºã¥ããã¢ããã¤ã¹ãããã¤ãããã¦ããã ãã¾ããã
éä¸ããã®éå¶åå ã§è²ã
ã¨å£ãæãã¨å¿«ãæããªã人ããããããããªãã¨æãããã¾ãåºããã°ããªãããã«å¿ããã¦ã¾ããã
ã§ãçµæã¨ãã¦åºããã°ã£ã¦ã¾ããããããããªããããããªããã
ãããéå¶ã£ã¦ãããªã«å¤§å¤ã ã£ããã§ãã
ç§ã¯ãã ã®ãæä¼ãè¦å¡ã§ããããããã§ãçµæ§å¤§å¤ã§ãããISUCONéå¶ã£ã¦ãããªã«å¤§å¤ã ã£ããã§ããã
ãã ã®ãæä¼ãã§ããã ã大å¤ãªã®ã«ãã¡ã¤ã³ã®éå¶ã®çæ§ãã©ãã ã大å¤ãã¯æ³åãã¤ãã¾ããã
çããéå¶ã®æ¹ã
ã«æè¬ãã¾ãããããããã¨ããããã¨ãã🙏
*1:ã§ããªãã¯ãªããQiitaã«Werckerã§Dockerãã«ããããè¨äºããã¾ã
ISUCON6äºé¸ã§æéãã¾ãããAzureã«è©³ãããªãã¾ãã
AppArmor Goã¨ã㦠@netmarkjp, @ishikawa84g, @matsuu ã§åæ¦ãã¾ãããæ®å¿µãªããå»å¹´ã«ç¶ãäºé¸æéï¼æ¨å®ï¼ã¨ãªãã¾ãããæçµã¹ã³ã¢ã¯24000ãããã§ãã
åºç¤
- ãããã¤ãçµãã£ã¦ä½ãå¤æ´ãã¦ããªãç¶æ
(ããã©ã«ãã®perlå®è£
)ã§ãã³ããã¼ã¯åã
- âã¹ã³ã¢0
- Goè¨èªã«åãæ¿ãã¦ãã³ããã¼ã¯åã
- âã¹ã³ã¢0
- MySQLã«é©åãªã¤ã³ããã¯ã¹è¿½å ãhtmlifyã®æ£è¦è¡¨ç¾çæãåãåºãã¦entryã®è¿½å /åé¤ãããã¾ã§æ£è¦è¡¨ç¾ããã£ãã·ã¥ãã¦ä½¿ãã¾ãã
- âã¹ã³ã¢0
ãã¼ããã§ããã¡ãã¼ã¨æãã¤ã¤æ¼é£ã§æ°å転æã
ä¸ç¤
æ¼é£ã§æãã¤ãã¾ããã
- åæç¶æ ã§entryãã¨ã«ããããããã¼ã¯ã¼ããäºãæ½åºãã¦ãã£ãã·ã¥ããentryã®è¿½å /åé¤ããããã¨ã«entryãã¨ã®ãã¼ã¯ã¼ããã£ãã·ã¥ãããæãã«èª¿æ´ãããã¨ã§æ£è¦è¡¨ç¾çæã®ã³ã¹ããä¸ãããã¨ãã
- Goã®regexp.Regexpã®å©ç¨ã諦ãã¦PCREå®è£
ã試ã¿ããã¨ãã
- âå®ç¾å¯è½æ§ãçã£ã¦ãã¾ããã¾ãæãé²ã¾ãªã
- ãã®ãããããå³å¾å·¦å¾
ã¤ãã¤ã¤ãã¤ã¨ãã®ãããã§å°ãç¦ãå§ããã
çµç¤
ãã®æç¹ã§16:30ãæªã ã¹ã³ã¢0ã®ã¾ã¾ã
- Goãä¸æ¦è«¦ãPerlã«åãæ¿ããhtmlifyã®æ£è¦è¡¨ç¾çæããã£ãã·ã¥ããã¨ããã¾ã§å®è£
- âã¹ã³ã¢10000ã¡ãããè¨é²ãã¾ãããF***ãGoã¤ããã
- ããããã¹ã¿ã¼ãã©ã¤ã³ã ãPerlã§ããã«ããã¯ã調ã¹ã¦æ½°ãã¦ããã
- ä¹ ã ã®Perlã§ãã£ããDevel::NYTProfã®ä½¿ãæ¹ãå¿ãã¦ãã¾ã£ã¦ãããããã«ããã¯ããã¡ãã¨ææ¡ã§ããªãã¾ã¾ã®æªæ¦è¦é
æå¾ã«ã¹ã³ã¢24000ããããè¨é²ãã¦ãã£ããã·ã¥ã§ãããã¤ããã
åçä¼
Goã§æ£è¦è¡¨ç¾ã®Compileãé ãã®ã¯äºåã«ææ¡ãã¦ããã®ã§ããããããã©ãã«ãããæ¹æ³ãæãã¤ããæ¨æã§ãããã¾ãGoã諦ããå¤æãé ãã£ããGo以å¤ãåå¼·ãã¦ããã°ããã£ããè¤æ°ã®è¨èªã«å¯¾å¿ã§ããããã«ãã¦ãããã¨ã¯å¤§äºã§ããã
ãã¨ã§èãã話ã«ããã¨golangã§ããã°strings.Replacer ã使ãããããã§ãããªãã»ã©ã¼ããããèªåã®ç¥èã¨ã°ã°ã©ããªãã£ã§ã¯ãã®æ å ±ã«ãã©ãçããã¨ã¯ã§ããªãã£ãã§ããããåç¡ã
ã¾ã¨ã
äºç¿ã®ãããã§Azureã«éå詳ãããªãã¾ãããä»å¾ã®ä»äºã«å¤§ãã«å½¹ç«ã¡ãããªæ°ããã¾ãã
ISUCONã§ã¯è² ãã¾ãããã大ããªæ¦æãå¾ããã¨ãã§ãã¾ããããããã¨ãéå¶ãããããã¨ãISUCON!
ISUCON6äºé¸ã®éå»åVagrantãä½ãå§ãã¦ã¾ããä¹ããæå¾ ã
ISUCONã®ç·´ç¿ã«ä½¿ããç°å¢ãå種ãç¨æãã¦ããã¾ã
ååã®è¨äºãISUCONãã¿ã ã£ãmatsuuã§ããISUCONã®ãã¨ããæ¸ãã¦ãªãããªã
ISUCONで良いスコアを叩き出すためには過去問を解くことが大事ã¨1å¹´åã«ãæ¸ããã¦é ãã¾ããããä»åãæ§ã ãªç°å¢ã§éå»åã«ãã£ã¬ã³ã¸ã§ããããã«ãã¾ãããã©ãããæ»åãã ããã
Microsoft Azure
ä»åã®ISUCON6ã¯Microsoft Azureä¸ã§è¡ãããã¨ãããã¨ã§ãAzureç¨ãã³ãã¬ã¼ããç¨æãã¾ãããã¯ãªãã¯ããã ãã§Azureç°å¢ã«ãããã¤ãå¯è½ã§ãã
https://github.com/matsuu/azure-isucon-templates
ISUCON5äºé¸ã¨Pixivããã®ç¤¾å
ISUCONããããã¤ãããã³ãã¬ã¼ããç¨æãã¦ããã¾ãã
å
é¨çã«ã¯çã£ãããªOSä¸ã§Ansibleã«ãããããã¸ã§ãã³ã°ãè¡ã£ã¦ããããæ§ç¯ã«1æéå¼±ãããã¾ãã®ã§ãäºæ¿ä¸ããã
ä»ååãã¦ãã³ãã¬ã¼ããä½ã£ãã®ã§æãæ¼ããããããããã¾ãããåé¡ãããã°éæãææãã ããã
Vagrant
ååã®Vagrantç°å¢ãæ´æ°ãã¾ããã
https://github.com/matsuu/vagrant-isucon
https://github.com/matsuu/vagrant-pixiv-isucon2016
vagrant upãå®è¡ããã°Ansibleã«ãããããã¸ã§ãã³ã°ãå§ã¾ãã¾ããboxã®é
å¸ã¾ã§ã¯è¡ã£ã¦ããã¾ãããããããªããã
Ansible
åæ§ã«Ansibleç°å¢ãæ´æ°ãã¦ãã¾ãã
https://github.com/matsuu/ansible-isucon
Pixivããã®ç¤¾å
ISUCONã¯公式リポジトリのAnsibleããå©ç¨ãã ããã
Terraform
éå»åã®æ¬å®¶AMIãªã©ãèµ·åããããã®Terraformãç¨æãã¦ãã¾ãã
https://github.com/matsuu/terraform-isucon
https://github.com/matsuu/terraform-pixiv-isucon2016
移æ¤çãå«ã¾ãã¦ã¾ãã移æ¤çã¯ãããã¸ã§ãã³ã°ã«Ansibleã使ãããã®ã§æ§ç¯ã«æéããããã¾ããã注æãã ããã
Docker
ä»åãã¹ãçã«Dockerç°å¢ãç¨æãã¦ã¿ã¾ããã
https://github.com/matsuu/docker-isucon
ã¨ããããä½ããããããªISUCON4äºé¸ã§ä½ã£ã¦ã¿ã¾ããããAnsibleããDockerfileã¸ã®æ¸ãæãã§ããªãç²å¼ããããããä½ãããããã¾ããã
Docker Hubã§AUTOBUILDãåãã¦ããã®ã§dockerã³ãã³ãã§ãã¦ã³ãã¼ãå¯è½ã§ããåè¨èªãã¨ã®docker-compose.ymlãç¨æãã¦ãã¾ãã
ã¾ã¨ã
ç°å¢æ§ç¯ã°ãããã£ã¦ãã¦éå»åã解ãæéããªãã§ããä½ãã£ã¦ãã ã
ã¿ãªããã®ãå½¹ã«ç«ã¦ã°å¹¸ãã§ãã