git challengeの自動採点高速化に向けたインフラのハナシ
git challengeのインフラを担当している2016年度新卒エンジニアの轟 (@tdrk18) と、2017年度新卒エンジニアでSREの見習いをやっております佐藤 (@jtwp470) です。今回は、git challengeという技術競技イベントの自動採点の高速化に向けたインフラのお話です。
git challengeとは
git challengeとは、gitを使う上で起こり得る問題を、ふたり一組のチームで解いていく競技形式のイベントです。 各チームに設問ごとのリポジトリが与えられ、問題点を解消した差分をコミットし、それをリモートリポジトリにpushして解き進めていきます。
git challenge についてはこちらをご覧ください。
また、git challengeの運営に関するインタビュー記事も用意していますので、あわせてご覧ください。
git challengeのインフラについて
git challengeのインフラ構成およびその変遷をご紹介します。
各チームの解答がリモートリポジトリにpushされると、自動で採点スクリプトが動作し、採点結果が自前のスコアボードやSlackに通知される仕組みになっています。
リモートリポジトリにはGitHubのプライベートリポジトリを利用し、採点にはCI (継続的改善) を利用しています。
第1回〜第3回大会までのインフラ構成
第3回大会までは、採点に利用するCIサービスとしてCircleCIを利用していました。
CircleCIはGitHubと簡単に連携できるようになっており、GitHubアカウントを使うことでCircleCIにログインすることができます。
GitHubへのpushを検知してCircleCI上で採点スクリプトを動作させ、pushされた解答に対して採点スクリプトを走らせていました。その結果がスコアボードやSlackに飛び、解答の正誤がわかるようになっています。
[fig.1 第3回大会までのインフラ構成]
旧インフラシステムの問題点
GitHubにはAPI rate limitがあり、ベーシック認証またはOAuthを利用する場合、1時間に5000リクエストまでという制限があります。
GitHubへのpushを検知し、最新の解答をcloneしてきて採点をするという方法をとっていたため、短時間に多くの解答が提出されると、GitHubへの大量のリクエストが必要なため、API rate limitに引っかかってしまいます。そうすると、参加者のみなさんの解答を GitHubからcloneできず、採点ができなくなってしまいます。第2回大会までは運営が用意したアカウントを全チームの採点に共通で利用していたため、実際にAPI rate limitに引っかかってしまい、スタッフが手元のマシンで採点を行う「ヒューマンCI」が登場しました。想像に難くないと思いますが、自動で行うはずだった作業を人手で行うことになったことで、運営スタッフもバタバタしてしまい、参加者の皆様にご迷惑をおかけしてしまいました。競技会場のハッシュタグ#mixi_gitの様子はこちらです。
人間CI始まってる #mixi_git
— Pocke(ぽっけ) (@p_ck_) 2016年3月5日
CircleCIの復旧を待ちつつお弁当タイム #mixi_git https://t.co/UQ8MjeJkMN
— mktakuya (@mktakuya) 2016年3月5日
この出来事を受け、第3回大会からは、参加者のみなさんのアカウントを採点に利用していただくことにしました。リクエストを送るアカウントが分散したことにより、API rate limitに引っかかることはなくなりました。しかし、事前設定を参加者のみなさんにしていただく必要があり、開始までに時間がかかってしまうという課題が見えてきました。
第4回大会におけるインフラ構成の移行
第4回大会からは、参加者のみなさんへの負担を減らすため、CircleCIに代わってAWS上にオープンソースのCIツールであるJenkinsを設置し、自動採点システムを構築することにしました。
[fig.2 第4回大会以降のインフラ構成]
Jenkinsを利用してよかったこと
以前はGitHubとCircleCIの連携を参加者にやっていただいていましたが、Jenkinsが自分たちの管理下にあることで、あらかじめGitHubとJenkinsの連携を仕込むことができ、当日の準備の時間や学生さんの負担を減らすことができました。
また、CircleCI上の採点では、必要なモジュールを都度インストールする必要がありましたが、あらかじめモジュールのインストールも済ませておけることにより、採点にかかる時間も短縮することができました。
CircleCIからJenkins移行で大変だったこと
CircleCIにおいて、CIの処理や設定のうち大部分はYAMLファイルで宣言的に記述することができました。また、GitHubとの連携やその他細々としたことも、意識せずに利用できました。一方、Jenkinsを利用する際に、これまでCircle CIに任せていた設定を自分たちで設定する必要があり、その中で次のような問題に直面しました。
GitHubからコードをcloneし採点スクリプトを動かすための設定をしたのですが、いくつかの採点スクリプトが期待通りに動作しませんでした。
調べていくと、Argument list too longというメッセージが出ていました。そこでJenkinsのイシュートラッカーを探してみると似たようなイシューJSON-editor with File-Upload causes "Argument list too long" fatal errorが見つかりましたが、決定的な解決策が見つからず、八方塞がりになりかけました。
ここで、失敗している問題を追ってみると、コミットログが数千もあるようなリポジトリであり、その問題のGitHubから送られるpayloadは、そのすべてのコミットログを含む巨大なリクエストとなっているということがわかりました。その巨大なpayloadが環境変数に設定されることが原因で、採点スクリプトの実行に失敗していました。私達が採点に利用するパラメータはチーム名とリポジトリ名の2つだったため、プロキシのようなものを用意し、GitHubから送られてくるpayloadから必要なもののみを切り出して環境変数に設定することでこの問題を解決しました。
Argument list too longはLinuxの制限のため、一旦はカーネルパラメータを書き換えて環境変数の長さを変更するようにカーネル自体をカスタムビルドしないと対応できないか? などと考えてしまいましたが、メンバーの気づきによりこの問題を回避し、少ない工数で解決することができました。
第5回大会におけるインフラ構築の自動化
2017年1月28日に開催された第5回大会に際し、第4回以前の開催準備や競技当日を振り返ると、「インフラ構築を手動で行っており、コストが大きい」という課題が浮かび上がってきたため、これを自動化により解決しました。
インフラ構築の自動化
第4回までのインフラの構築は、手順書にもとづき人間がコマンドを入力するという昔ながらの手法をとっていました。これには時間がかかり、また間違いも起きてしまう可能性があります。そこでAnsibleを利用し、一連のセットアップを自動化しました。またインフラ構築も同様に自動化をするためTerraformを利用し、Infrastructure as Codeの実践を行っています。
最後に
git challengeのインフラ準備は、主に1〜4年目の若手エンジニアが担当しています。参加者の方々が楽しく挑戦していただけるよう、これからも改善を続けていきます。
git challengeは今後も開催を予定しています。ご興味ある学生のみなさん、会場でお会いしましょう!以下のページからご応募よろしくお願いします。第6回大会は2017年9月2日に開催予定です。