はじめまして。sou7といいます。会津大学の学部4年生です。訳あって留年してしまったので、この記事を書いている4/1現在も学部4年生です。
今回はピクシブの長期インターンに参加してきたので、それについて参加記を書きたいと思います。
なぜピクシブの長期インターンに参加したのか
自分はこれまでOSSコントリビュートや個人での開発をメインに行ってきました。しかし、チーム開発をする経験がこれまでほとんどありませんでした。そのためこの先の就活1に向け、チームの一員となって働くことへのイメージを固めたかった、というのが一番の目的でした。
また、数あるインターンの中からピクシブを選んだ理由は以下の2つです。
- これまで触ってきたRubyの経験を活かせそうだから
- RubyKaigi2023の学生支援プログラム、PIXIV DEV MEETUP 2024への参加など、ピクシブとのつながりがあったから
取り組んだ課題
メインとして頂いたタスクは「Active Jobの安定化」というものでした。まず、Active Jobがどこで使われていて、どのようなものなのかについて説明します。
pixiv Ads
自分が配属された部署は、pixiv Adsというサービスを開発しています。pixiv Adsは簡単に言うとTwitter広告のピクシブ版で、ピクシブの各サービスへの運用型広告を行うサービスです。純広告(広告主と直接やりとりし、特定の枠を利用して行う広告)と第三者配信広告(Google AdSenseなど)の間を取り、ピクシブが持つファーストパティーデータを利用しながら、入札による配信の最適化を行った広告配信を行います。
自分が配属されたチームは、このpixiv Adsのうち、広告主さま、広告代理店さま、そしてピクシブの社員の方が利用する管理画面を開発しています。ピクシブでは珍しく、主に企業の方が利用するサービスになります。
Active Job
pixiv Adsの管理画面のバックエンドはRailsで開発されています。Railsにおけるメール配信や画像処理などの非同期処理を行う部分のライブラリがActive Jobです。
Active Jobはジョブの管理のためにキューイングを行います。キューイングを行うバックエンドのライブラリはAsyncAdapter, Sidekiq, Solid Queueなど、アダプターを介して複数の実装から選択することが出来ます。
自分がこのタスクを取り組み始めたときは、AsyncAdapterというキューを使用していました。しかし、このライブラリには問題点があり、pixiv Adsにおけるリスクとなっていました。具体的には、AsyncAdapterはインメモリのキューでジョブを管理するため、Podのシャットダウン時などにデータが損失し、メールが送られない可能性がありました。
取り組んだ内容
取り組んだ課題の内容としては、主に以下のようなものがありました。
- AsyncAdapterの代わりとなるライブラリの調査
- 移行するための設定の変更
- Solid Queueのワーカープロセスを動かすためのDeploymentを追加
- Kubernetesのヘルスチェックに対応するための設定を追加
- 正常にジョブを消化できていることを確かめるためのタスクを追加
直面した選択
実装を進める中で、複数の選択肢がある中から選ぶ作業をたくさん経験しました。その中から次の2つの選択についてお話します。
Solid Queueで使用するデータベースをどうするのか
Solid QueueはMySQLやPostgreSQL、SQLiteといったRDBを利用してジョブを管理します。pixiv AdsではCloud SQLを利用していますが、その際にインスタンスを作成するのか、それとも既存のものと共有するのかという選択肢があります。
その中から、今回はデータベースを共有するという選択をしました。インスタンスを増やすと安定性が高まる代わりにコストがかかります。このサービスはそれほど流量が大きくなく、安定性とコストのバランスを考えるとインスタンスは増やさない選択になりました。
ワーカープロセスはどこのコンテナで動かすのか
Solid Queueはジョブの処理を、Railsのコマンドとは別のコマンドで行います。このコマンドをどこで動かすかについて、3つの選択肢がありました。
- Railsのコンテナと共有し、1つのコンテナで複数のコマンドを動かす。
- Podのサイドカーコンテナを利用する。
- ジョブの処理を行うためのDeploymentを作成する。
1.の選択肢については、graceful shutdownが大きな課題となりました。Podが終了する際には、コンテナのメインプロセスに対してSIGTERMが送信され、SIGTERMを受け取ったプロセスは処理を完了した後に自らプロセスを終了させます。1コンテナ2プロセスを行うためにラッパースクリプトを書く場合、SIGTERMを正常に各プロセスに伝える必要があります。また、片方のプロセスが死んでしまった際の処理など考慮するべき点が多く、複雑な処理が必要になります。そもそもこの責務はKubernetesが担うべきものであり、1つのコンテナに複数のプロセスを動かそうとするのは筋が悪いと考えました。
2.の選択肢については、Solid QueueのコンテナとRailsのコンテナを同一のPodで動かす形になります。しかし、Solid QueueのコンテナとRailsのコンテナは直接は通信せず、データベースを介して通信します。直接通信しないコンテナをサイドカーコンテナとして動かすのは本来の用途と異なっている感触があり、この選択肢も避けることになりました。
これらを考え、最終的に3.の選択肢を選ぶことになりました。Deploymentを一から書く必要があり少し手間は掛かりますが、安定性も高く、将来の変更にも耐えやすい設計ではないかと考えています。
インターンを通して成長できた点
初めて触る技術を体験できた
Rails、Kubernetes、Argo CD、Datadogなど、初めて触る技術がたくさんありました。今回のタスクに見合うレベルまでキャッチアップするのは大変でしたが、メンターの方や、チームメンバーの方のおかげでなんとか遂行することが出来ました。
チーム開発の経験を積めた
自分は個人開発やOSSコントリビュートをメインにしていて、チーム開発を行った経験は多くありませんでした。今回のインターンの中で、意思決定をするために手を動かして情報を集め、整理して説明し、そして実装に取り掛かるという経験をたくさん積むことが出来ました。
社員の方にたくさんのお話を伺えた
5週間のインターン期間のうち、1週間の間はオフィスに出社させていただきました。この出社の期間で、たくさんの方とご飯に行き、この先待ち構える就活についてアドバイスを頂きました。特に、ユーザーの満足度と会社の関係についてのお話が記憶に残っています。
おわりに
メンターやチームメンバーの方に助けて頂き、多くのポイントで成長することが出来ました。5週間ありがとうございました。
ピクシブは通年で長期インターン/アルバイトを募集しています。興味のある方はぜひ応募してみてください!
Footnotes
-
大学院に進学する予定なので、27秋卒または28卒の予定です。なので、就職活動まではしばらく時間があります。 ↩