Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

【福岡はいいぞ】福岡拠点開発部の「気軽な」ノリで ISUCON12 に出場した話

こんにちは宮村(みやむー) @miyamura.koyo です。 2021年9月に福岡のクラウド経費・債務支払開発部にサーバエンジニアとしてジョインして開発を行なっております!

今回は福岡拠点のクラウド経費債務支払 開発チームが今年の ISUCON12 に出場した話を書いてみたいと思います。 ※ ISUCON (= Iikanjini Speed Up Contest)とは毎年開催されているWebアプリケーションの高速化チューニングコンテストです。

なお福岡拠点では、様々な取り組みがメンバー起点で行われており、とても働きやすい環境です。 その雰囲気の一端を感じてもらえればと思います。

参加の経緯

私は前職、面白法人カヤックという会社で働いていました。 ISUCON は前回大会の優勝者が出題を行うという文化があるのですが、ISUCON11ではカヤックチームが優勝したので、ISUCON12の出題はカヤックが行いました。 というわけで「前職の出題だし是非参加したい!」と思い、参加を決めました。

ISUCON は最大3人参加できるので、仲間を集めたい!と思い社内で募ってみました。 すると大先輩である野田さん江口さんが誘いに乗ってくれて、3人でやるぞ!となったのが参加経緯です。 気軽に誘える環境いいなぁと再実感した出来事でした。

1ヶ月前 ~ 当日まで

まず Slack の専用チャンネルを作りました! そしてちょうど発売された 達人が教えるWebパフォーマンスチューニング 〜ISUCONから学ぶ高速化の実践 をみんなで読みました。 個人的には、著者が実際に練習問題をどういう思考過程で解いたかが書かれているところが一番勉強になりました:pray:

また、週末に数回勉強会を実施して過去問を解いて知見を深めました。 ISUCON運営の方からスポンサークーポンいただいて、過去問環境を整えて解いたり、以下のようなカンペ作ったりしていました。

ちなみに参加言語は普段使ってるし Ruby にしよう!と決めました。 なお ISUCON 未経験メンバーもいたので、予選突破目指すよりは、普段の業務でやらないことを体験して学んだり、ISUCON を楽しむことをメインにやっていました。

当日

当日はオフィスに集合して、ワイワイやっていました。

私は Makefile を準備して以下のような運用をしていました。 (※ alppt-query-digest を使う ISUCON 定番構成です。)

  • make init でディレクトリの準備
  • make install-tools でツールのインストール
  • ベンチマーク実行前に make prepare-bench ベンチ実行後に make after-bench を実行
# isucon ユーザーじゃなければ適宜変更する
export ISUCON_USER=isucon
export ISUCON_GROUP=isucon
export NGINX_USER=root
export NGINX_GROUP=root
export MYSQL_USER=root
export MYSQL_GROUP=root
# 初回に実行する
# ディレクトリ作成・nginx / mysql の設定ファイルを取得
init: init-dir get-nginxconf get-mysqlconf
init-dir:
mkdir -p conf/nginx/sites-enabled
mkdir -p conf/nginx/sites-available
mkdir -p log
# 各ツールのインストール
install-tools: install-pt-query-digest install-alp install-command
install-alp:
wget https://github.com/tkuchiki/alp/releases/download/v1.0.9/alp_linux_amd64.zip
sudo apt-get install -y unzip
unzip alp_linux_amd64.zip
sudo install ./alp /usr/local/bin
rm alp
rm alp_linux_amd64.zip
install-pt-query-digest:
sudo apt-get update
sudo apt-get install -y percona-toolkit
install-command:
sudo apt-get install -y rsync
# 必要なら実行
# デフォルト 11211 ポート
# ※ Ruby の場合は Gemfile に gem 'dalli' を追加するなどクライアントのダウンロード別途必要
install-memcached:
sudo apt install memcached
# 本番のサーバー構成に合わせて適宜書き換える
set-nginxconf:
sudo rsync -rv conf/nginx/nginx.conf /etc/nginx/nginx.conf
sudo rsync -rv conf/nginx/sites-enabled/* /etc/nginx/sites-enabled
sudo rsync -rv conf/nginx/sites-available/* /etc/nginx/sites-available
sudo chown ${NGINX_USER}:${NGINX_GROUP} /etc/nginx/nginx.conf
sudo chown -R ${NGINX_USER}:${NGINX_GROUP} /etc/nginx/sites-enabled
sudo chown -R ${NGINX_USER}:${NGINX_GROUP} /etc/nginx/sites-available
set-mysqlconf:
sudo rsync -rv conf/mysqld.cnf /etc/mysql/mysql.conf.d
sudo chown ${MYSQL_USER}:${MYSQL_GROUP} /etc/mysql/mysql.conf.d/mysqld.cnf
# 本番のサーバー構成に合わせて適宜書き換える
get-nginxconf:
sudo rsync -rv /etc/nginx/nginx.conf conf/nginx
sudo rsync -rv /etc/nginx/sites-enabled/* conf/nginx/sites-enabled
sudo rsync -rv /etc/nginx/sites-available/* conf/nginx/sites-available
sudo chown ${ISUCON_USER}:${ISUCON_GROUP} conf/nginx/nginx.conf
sudo chown -R ${ISUCON_USER}:${ISUCON_GROUP} conf/nginx/sites-enabled
sudo chown -R ${ISUCON_USER}:${ISUCON_GROUP} conf/nginx/sites-available
get-mysqlconf:
sudo rsync -rv /etc/mysql/mysql.conf.d/mysqld.cnf conf/
sudo chown ${ISUCON_USER}:${ISUCON_GROUP} conf/mysqld.cnf
# 現状のログをリポジトリ配下にコピー
copylog:
sudo cat /var/log/nginx/access.log > /home/${ISUCON_USER}/log/nginx-access.log
sudo cat /var/log/mysql/slow.log > /home/${ISUCON_USER}/log/slow.log
# pt-query-digest と alp でログを解析
# NOTE: alp の -m オプションの引数は適宜変更する
analyze:
pt-query-digest cat /home/${ISUCON_USER}/log/slow.log > /home/${ISUCON_USER}/log/ptqd-result
cat /home/${ISUCON_USER}/log/nginx-access.log | alp ltsv -m "/api/player/competition/.*/ranking,/api/organizer/competition/.*/score,/api/organizer/competition/.*/finish,/api/player/player/.*,/api/organizer/player/.*/disqualified" --sort=sum -r > /home/${ISUCON_USER}/log/alp-result
# 現状のログとその解析結果を git 配下にコピー
save-log:
if [ -f "/home/${ISUCON_USER}/log/nginx-access.log" ]; then mv /home/${ISUCON_USER}/log/nginx-access.log /home/${ISUCON_USER}/log/nginx-access-`date "+%Y%m%d_%H%M%S"`.log ; fi
if [ -f "/home/${ISUCON_USER}/log/slow.log" ]; then mv /home/${ISUCON_USER}/log/slow.log /home/${ISUCON_USER}/log/slow-`date "+%Y%m%d_%H%M%S"`.log ; fi
if [ -f "/home/${ISUCON_USER}/log/ptqd-result" ]; then mv /home/${ISUCON_USER}/log/ptqd-result /home/${ISUCON_USER}/log/ptqd-result-`date "+%Y%m%d_%H%M%S"` ; fi
if [ -f "/home/${ISUCON_USER}/log/alp-result" ]; then mv /home/${ISUCON_USER}/log/alp-result /home/${ISUCON_USER}/log/alp-result-`date "+%Y%m%d_%H%M%S"` ; fi
# ベンチ回す前に、以前の nginx / mysql のログを削除
cleanlog:
sudo sh -c "echo > /var/log/mysql/slow.log"
sudo sh -c "echo > /var/log/nginx/access.log"
# 各デーモンの再起動
# NOTE: isucondition.ruby.service は適宜変更する
# memcached.service 入れる場合は以下も追加
# sudo systemctl restart memcached.service
restart:
sudo systemctl restart nginx
sudo systemctl restart mysql
sudo systemctl restart isucondition.ruby.service
# ベンチ回す前の準備
prepare-bench: set-nginxconf set-mysqlconf restart cleanlog save-log
# ベンチ回した後のログ解析
after-bench: copylog analyze
# 簡易的に git に push
push:
git add .
git commit -m "push from Makefile"
git push origin main
view raw Makefile hosted with ❤ by GitHub

概ね以下のような流れでやっていました。

  • マニュアルを読んでアプリケーションを理解する
  • 事前準備した Makefile を適用して、検証サイクルが回せるようにする
  • インデックスを貼ったりアプリケーションロジックの変更を行う
  • 最後にログ消したりお片付け

なお今回の予選は MySQL と SQLite の混在システムで、MySQL に寄せるか悩みましたが、さすがに時間内に終わらないかということで SQLite のまま頑張りました。

個人的には uuid 発行部分を SecureRandom.uuid にできたのが Ruby らしい解法ができたなと思っています。 ちなみに反省点としては、自作の make コマンド実行時に slow.log がなかったので touch コマンドで適当に空ファイル作ったところ、パーミッションがないせいでスロークエリが出ないことにだいぶハマったことですね笑 正常終了するのにログが出なくてだいぶハマりました。

結果

約199位/698チーム (約上位28.5%)でした。予選突破は遠いですが、Ruby で思ったより点数も伸ばせたので個人的には及第点! https://isucon.net/archives/56838276.html

ただ予選の講評を見ると、ここはもっとやれたなー!と思う部分もあって、次こそは!という気持ちになりました。 来年もまた福岡チームで出たいですね!

やってみて

私自身も含めた参加メンバーの感想です。

みやむー(筆者)

  • 仕事しながら準備して参加するの大変かなぁと思っていたのですが、先輩が快諾してくれて、色々と知見を教えてもらったり、一緒にワイワイできて楽しかったです。
  • ISUCON は2年前も参加していたのですが、その時に比べると格段にできることが増えていたので、自分の成長を感じることができました。
    • 一方で、まだまだだなぁと思うことも多かったので、これからも精進していきたいなと思います。
    • 特にファイルロックをトランザクションに変えるところは、あまり効果ないかなと思い放置していたところだったのでとりあえず試してみるべきだったなと思いました。すぐできるところでもあったし。

野田さん

  • ActiveRecord じゃなくて素の MySQL アダプタで N+1 を解決しようとしたり、SQLite でも使える Windows 関数でクエリを効率化しようとしたりしたが、あまり改善に結びつかなかった。
    • よくある改善方法を怪しい箇所にとりあえず適用するのではなく、きちんと計測するということの大切さを実感した。
  • SQLite 意外といいじゃんと思うきっかけになった。
  • ベンチマークを各メンバーで同一の環境で同期的に実行しないといけないのが大変だった。
    • 予期せずファイルのパーミッションや Nginx のよくわからないエラーでハマるのが辛い。アプリが当たり前に動かないもどかしさを感じた。

江口さん

  • 「計測しないと、改善したかどうかわからない」という当たり前の事実の重要さを肌で感じた。
    • ISUCON の考え方が、その後サービスの実行時間改善に取り組むときに役立ちました。

※また、江口さんはISUCON参加後に以下のような日記を書いているのでこちらもぜひ ISUCON のリアルな感情の動きが書かれています・・・! https://github.com/eggc/memo/blob/main/diary/20220723_isucon.org

まとめ

福岡開発拠点メンバーで ISUCON12 に参加して、いろいろな学びを得ました。 こんな感じで 「こういうことやりたいなー」と思った時に気軽に相談できる仲間がいる職場 です。 FinTech 業界ってお堅いんじゃないの?と思う方もいるかもしれませんが、そんなことはありません。 この記事で紹介したように、マネーフォワードは仕事は真剣にしつつも、柔軟に楽しく働ける会社です! 一緒に働きたい方ぜひお待ちしております!


マネーフォワード福岡拠点では、エンジニアを募集しています! 自分の興味を面白がって、乗っかってくれる職場で働きたい!そんな方はぜひぜひお話聞かせてください。 ご応募お待ちしています。

https://hrmos.co/pages/moneyforward/jobs?category=1666323298559537153

福岡開発拠点のサイトもあるのでぜひみてね!

https://fukuoka.moneyforward.com/


マネーフォワードでは、エンジニアを募集しています。 ご応募お待ちしています。

【会社情報】 ■Wantedly株式会社マネーフォワード福岡開発拠点関西開発拠点(大阪/京都)

【SNS】 ■マネーフォワード公式noteTwitter - 【公式】マネーフォワードTwitter - Money Forward Developersconnpass - マネーフォワードYouTube - Money Forward Developers