ISUCON5 の予選にメルカリのインフラ系エンジニアで結成したチーム「GoBold」で参加して、無事2位で通過しました。チームのメンバーは、@cubicdaiya、@shmorimo、@kazeburoの3人で、普段から横にならんで座って、メルカリのパフォーマンス改善やサーバ環境の整備に携わっています。

今回の予選問題、ずいぶん盛ってきたなーというのが最初の印象。モリスさんも予選問題を本選のようにしたいと言っていたし、その通りになっていました。マシンの性能に対しての扱うデータ量もメモリに乗り切らないであろうスレスレのラインでkamipoさんの調整も神だなと思いました。おかげでやることが満載だし、素晴らしい問題でした。運営の941さんも含め本当にお疲れさまでした。本選もよろしくお願いします。

チームのメンバーのblog

ISUCON5予選 2位で通過しました - 考える人、コードを書く人

やったこと

最終的なソースコードといくつかの設定はgithubで公開しました

https://github.com/kazeburo/isucon5-elimination-public

構成は、Nignx + Perl + MySQL + memcachedです。PHPは使ってないです。はい

課題となったサイトは、ISUxiというSNSサイト、日記、日記のコメント、足跡、そしてhome.plのようなトップ画面。元m社のたんぽぽチームとアプリ運用チームの2人いるチームとしては負けてはならない課題でした。結果はfujiwara組に負けましたが。。あーくやし

やったこととスコアを時系列に整理してみると、こんな感じ。全部で72回ベンチマークを実行。

time score
11:22:12    52  <rubyの初期スコア
11:43:41    557 <perlの初期スコア
12:30:23    818 
12:55:18    1121    <userのrequest単位のcache、パスワードのhashの計算をperlで行うように
13:05:18    0   
13:08:44    0       
13:18:33    0       
13:22:56    19      
13:25:04    0       
13:26:37    794 <ようやくsuccess
13:30:04    882     
13:34:47    1191        
13:37:15    1191        
13:41:08    1223        
13:43:06    1198        
13:46:40    0   
13:48:00    0   
13:52:11    916 
13:54:03    19  
13:55:23    19  
13:59:30    1883    <is_friendsがmemcachedとなる, commentsテーブルにentry_user_idカラムを追加
14:02:33    0   
14:04:29    1967
14:07:46    1926        
14:10:31    1947        
14:22:49    4
14:26:09    2144    <userをin memory化
14:29:41    2137        
14:38:35    20
14:41:18    2160        
14:48:39    1088    <enqueueが2つされる
14:48:39    1117         
14:51:26    2182        
15:06:01    17
15:13:24    2026    
15:18:41    4277    <comments_of_friendsのクエリ改善と足跡の集計をperlで行うように
15:23:25    4305        
15:25:50    4242        
15:29:41    4372        
15:32:21    4376        
15:36:00    7134    <relationsのクエリからOR anotherを削除
15:40:29    0
15:44:02    8166    <comments_of_friendsのクエリ改善。limit 1000がなくなる
15:49:47    18439   <entries_of_friends,comments_of_friendsのクエリ改善、relationsをつかう
15:53:24    18873           
15:56:05    18561           
16:00:03    18167           
16:07:13    19525           
16:11:47    22126   <nginxのoptimize、unix domain socketを使ったり
16:18:35    21333           
16:22:58    21378           
16:28:49    18497   <再起動。このあたりから再起動とwarmupの試験
16:45:34    16823
16:51:06    0
17:06:42    17623           
17:10:21    19950           
17:13:38    20102           
17:28:07    18107           
17:37:25    17
17:44:09    16217           
17:49:53    14297           
17:55:28    1571    <友達のいないユーザからのアクセスでエラー多発   
18:00:17    0
18:17:52    0               
18:20:51    21243   < warmupをcatで行うようになって再起動後もスコア安定
18:27:54    21622           
18:30:27    22719           
18:34:52    22845           
18:39:46    23553   <comments_of_friends limitの調整
18:46:30    24118           
18:53:47    26300   < comment数のN+1を改善
19:00:00    25861   < 最後の再起動試験

MySQLのクエリ数が多いので、そこを減らすことから取りかかり、relationsのmemcached化とuserのin memory化を先に進め、その後に比較的重いクエリをひとつひとつ解決していきました。fujiwara組と逆かも。

アプリケーションのコード変更は3人で話し合い、次に解決する課題を整理し @shmorimo と自分とで分担して作業を行っていきました。直接masterにpushしていたけど、p-rベースにしてコードの確認をやっていた方が手戻りが少なかったかなと思う。

MySQLの設定とwarmup

今回のデータは3GB近くあり、それに対してサーバのメモリが3.5GB、HDDはSSDではなく超遅いというのが特徴。そこで再起動試験で安定したスコアを出そうしたら、warmupが重要になる(ならなかったけど)ということで、いくつか工夫をしました。

my.cnfは以下

innodb_buffer_pool_size = 800M
innodb_flush_log_at_trx_commit = 0
innodb_flush_method=nosync
innodb_doublewrite = 0

bufferpoolを減らして、ODIRECTは使っていません。innodbのbuffer_poolだけに頼るのではなくdisk cacheで行う戦略をとりました。まるでMyISAMのようですね。

そしてアプリケーションの起動スクリプトには

/bin/cat /var/lib/mysql/isucon5q/*.ibd > /dev/null 

exec /home/isucon/.local/perl/bin/carton exec -- start_server --path /tmp/app.sock  --backlog 16384 -- plackup -s Gazelle --workers=10 --max-reqs-per-child 500000 --min-reqs-per-child 400000 -E production -a app.psgi

のように書いて、メモリに乗っけてからアプリケーションを起動するようにしました。おかげでアプリケーションサーバさえ起動していれば満足のいくスコアがでるようになっています。

反省

22000がでたところで、安心してしまいGo Boldに行かなかったところが反省。アプリケーションを変更するプロセスもよくしていって、本選は(fujiwara組に)勝ちたい。

このブログ記事について

このページは、Masahiro Naganoが2015年9月28日 17:30に書いたブログ記事です。

ひとつ前のブログ記事は「MyNA(MySQLユーザ会)会 2015年8月 でメルカリのデータベース戦略とPHPについて喋って来た」です。

次のブログ記事は「ISUCON5にチーム「GoBold」で参加して特別賞と3位でした」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja