🏃

Wantedlyの就業型インターンでリアルISUCONした話

2022/10/13に公開

はじめまして@haru_0_4です。先日Wantedlyで3週間の就業型インターンに参加してきました。
インターン期間中にブログにアウトプットしたいです!と宣言したので、振り返りも兼ねて、実施内容や雰囲気を伝えていければと思います。

参加決定まで

Wantedlyのことは、長期インターンを探していた時に利用させていただいていたので前から知っていました。
Wantedlyのサマーインターンについても、PodCastを聞いていたこともあり存在は知っていました。
しかし、風のうわさでWantedlyは技術力が高く「本当に優秀な人しか採用しない」と聞いたことがあり、自分にはどうせ無理だろうと応募するのをためらっていました。
そんな中、5月の中旬頃Wantedlyから直接スカウトのメッセージが届きました。
ありがたいことに私のプロフィールを見て一度話をしてみたいと言っていただき、一度面談をすることになりました。
そのまま選考に乗っていき、気が付けば参加が決定していました。(プロフィールを充実させておいてよかった。。)

インターンについて

Wantedlyのサマーインターンでは、実際の業務で成果を出す難しさを体験してほしいという思いの元、就業型のみが用意されています。
私は推薦基盤チームでサーバサイドエンジニアとして参加させていただきました。
インターンでは、3週間で成果を出すことが求められます。
最終日には成果発表があり、3週間で取り組んだことを社内のエンジニアの方々やインターン生にプレゼンテーションします。

取り組んだことタスク

タイトルにもある通り、インターンではリアルISUCONに取り組みました。
ISUCONのことを知らない方もいらっしゃると思いますので簡単に説明すると、お題となるWebサービスを、決められた期間・条件の中で限界まで高速化を図るチューニングバトルのことです。
私は実際に稼働しているサービスの中で、特定の条件下でタイムアウトを起こしている機能があったので、そのパフォーマンスを改善させるための原因調査とチューニングに取り組みました。
どのタスクに取り組むかは、メンターがいくつか用意してくださった中から自分で選べる形で、私は当時マイクロサービスに興味があったので、周辺の技術に触れられるタスクをやりたいといったところ、メンターの方が僕の要求を満たすタスクを選んでくれたので、取り組むことにしました。

https://isucon.net/

どういった問題があったのか

Wantedly Visitでは、「つながり」という機能があり、簡単に言うと、自分の友達のようなものです。
今回のタスクでは、この「つながり」の数が、つまり友達の数が多いユーザにおいて、人名検索をした際にタイムアウトされてしまい、検索結果が表示されないという問題がありました。
私は、これらのユーザを救うべく、タイムアウトを起こさないようにパフォーマンスチューニングを行っていきました。

どうやって進めたか

問題を解決するために、以下の手順で進めました。

  1. New RelicのAPMを用いて、遅いトランザクションを見つける
  2. 遅くなっているトランザクションに計測ログを入れて、どの処理で遅いかを調査
  3. PostgreSQLの実行計画を表示
  4. 実行速度が遅くなっている処理に対して、ひたすらチューニングしていく

ISUCONもパフォーマンスチューニングも初めての経験だったこともあり、進め方が全く分からず、メンターの方を頼りながら手探りで進めていきました。

原因はどこだったのか

では、結局どこの何が原因だったかという話をしていきます。
結論から申し上げますと、以下の共通の友達を数えるSQLクエリ(NDAの関係でかなり端折っています)でかなり時間がかかっていました。
どうやらIN句の中にあるサブクエリで取得する件数が多いほど、SQLの実行速度が遅くなるみたいです。

SELECT user_id, count(*) 
FROM table_name
WHERE hogehoge_id in (
SELECT hoge_id FROM table_name 
WHERE hoge_id = (~) LIMIT 100000
) 
GROUP BY id; 

どうやって解決したか

原因のクエリの処理を単純なデータ取得だけにとどめ、ロジックはGoで実装することで解決しました。
具体的には以下の手順で分解していきました。

  1. サブクエリをクエリから分割
-- サブクエリ
SELECT hoge_id FROM table_name WHERE hoge_id = (~) LIMIT 100000
  1. ロジックを切り離す
-- メインクエリ
SELECT user_id FROM table_name WHERE hogehoge_id = (~); 
  1. 切り離したロジックをGoで実装する
func CalculateMutualFriendsByUserID() {

// 共通の友達を数える処理

return ~
}

成果

最終的な成果としては、チューニングを行った機能のレスポンスタイムが大幅に改善され、問題であったタイムアウトも起きないようにすることができました。
インターン最終日にリリースもされ、本番環境での平均レスポンスタイム、95パーセンタイル、99パーセンタイルも改善されていることを確認することができました。

インターンで感じたこと

1番の学びは、「手段に拘らない」ということです。
つまり問題解決のための試行回数を増やし、高速にPDCAを回すということが業務を素早く進めるためには重要だということです。
プロジェクトを進めるためには、複数の選択肢が存在すると思います。
Aの方法を試し、無理そう。時間がかかりそう。と思ったら、すぐBを試すという5~10分のサイクルを何度も繰り返すことで徐々に進めていくことができます。

メンターからのフィードバック

よかった点としては以下の点を指摘していただきました。

・プロジェクトを進める力は全体的に高い
・自身の進め方の振り返りを行い生産性をあげようとしていた

特にソフトスキル面について評価していただけました。
ただ自分の中で課題もあるので、もっと磨いていきたいと思います。

一方で、これからもっとよくしていけると指摘いただいた点についてです。

・成果を出すために必要な技術力が不足しているので伸ばしていけると良さそう
・何をやるとタスクが完了できるか筋道立てて実行できると良さそう

今回はGoの文法やSQLの知識が不足しており、業務を進める上での障害となっていたので、もし次参加するとすれば、ここの勉強をしっかりした上で参加したいと思います。
また始めの方では目標を決めずにやみくもに作業をしていたことで手戻りが何度か発生してしまっていたので、事前にゴール設定や条件の統一などが必要だということを学びました。
また、与えられたタスク(プロジェクト)を素早く正確に遂行するために、ちょっとした生産性を上げることや、コミュニケーションの仕方(質問の仕方)、仕事の進め方なども重要だと感じました。

インターンの雰囲気

また困ったらSlackやGoogle Meetでメンターの方が相談に乗ってくれたり、進捗が出ない時には「困っていることがあったらいつでも言ってくださいね!」と声をかけてくれる環境だったので、常に心理的な安心がありました。
未経験の技術もたくさんあったので成果が出るか不安もありましたが、メンターの方が非常に心強く、自分も自然と何とかなるかと思えるような環境でしたので、私のように技術的に不安がある方でも努力次第で戦うことができると思います。

会社の印象

会社の雰囲気はとても落ち着いていて、私が参加したチームのメンバーもギークで論理的に話す方が多く、居心地がいいなーと感じました。
またやりたいといえばなんでもやらせてもらえる雰囲気があり、皆さん「最短距離で最大社会的インパクト」を念頭に行動をとっていて、会社のミッションがしっかり根付いていることに感心しました。
会社のことをよく知るために、いろんなチームの方とお話をしたり、始めの1週間は物理出社させていただくなどの行動をとったこともあり、会社のことはよく知ることができました。
毎週開かれるデモ会では、全社員活気があり、プレゼンターが素晴らしい発表をした時には、すごい盛り上がりでびっくりしました。

↓初日にエンジニア向けのハンドブックやカルチャーブックなどがもらえました💪

おわりに

Wantedlyのインターンに参加して、以下の技術を積むことができました。

  • プロジェクトを手戻りなく素早くかつ正確に進める方法
  • SQLのバッドノウハウ
  • GoやRailsで実装されたマイクロサービス間のgRPC通信の仕組み
  • Wanteldyの社員のカルチャーやマインド

そのほか、技術力だけでなくプロジェクトを効率よく進める方法や生産性の上げ方など汎用的なスキルが身についたと思います。
3週間の間で、実際の仕事の難しさも感じつつ、成長を感じることができました。
参加できて良かったなと思っています。
インターンに関わっていただいた社員の皆様、大変お世話になりました。ありがとうございました!

Discussion