ID:72353さん

2025年2月回 指名


まだ何もありません

あなたを気にしている企業

3年後の目標や野望


海外で活躍できるほどのエンジニアとしての実力をつけたい。

世界レベルの技術力を持つエンジニアと共に働きたいから。誰もが知っている世界的に有名なサービスの開発に携わりたい。

プロジェクト経験

2024年/3ヶ月以内

メモリ使用量が多い非同期ジョブを別の実行基盤に移行するプロジェクト

## 背景 元々、メモリ使用量の多いバッチ処理を **Sidekiq** で実行していましたが、以下の課題が発生しました。 1. **メモリ使用量の問題** - 例えば、「ある日付の特定の時間に対する空き枠」のように、数十億件を超えるレコードを更新するジョブが増加し、Railsアプリケーションのメモリ使用量が急増。 - 一部のジョブがSidekiqのメモリ制限を超えてしまい、OOM Killerによってプロセスが強制終了されるケースが発生。 - 無料版のSidekiqをマルチスレッドで動作させていたため、プロセスがクラッシュすると、同一プロセス内の未処理のメッセージがすべて失われてしまった。 - メモリ使用量が大きいジョブの実行が失敗することで、結果を待つユーザーが長時間待たされる状況が発生。 2. **Sidekiq-Pro のコスト** - OOM Killerによる強制終了で、未処理のジョブがRedisのキューに残り続けないようにするため、**Sidekiq-Pro($99/月 ≒ 約15,000円)** の導入を検討。 - しかし、コストが高いうえに、ジョブの成功結果を待つユーザーの待ち時間は解消されない見込みだった。 このような背景から、**Sidekiq以外の実行基盤でバッチ処理を実行する方法** を検討しました。 --- ## 新しいシステム構成 Sidekiqを用いた非同期処理を **イベント駆動型(Event-Driven)** と **スケジュール駆動型(Schedule-Driven)** に分け、それぞれ別の実行基盤へ移行しました。 どちらも **Google Cloud Workflows から Cloud Run Jobs を起動** してバックグラウンド処理を行う設計です。 また、Cloud Run Jobs 内では **rakeタスク** を実行し、バッチ処理を実現しています。 ### **スケジュール駆動型(Schedule-Driven)ジョブの移行** 1. **Cloud Scheduler** が **Railsアプリケーションのエンドポイント** に対してHTTPリクエストを定期実行。 2. **Railsアプリケーション** 内で **Google Cloud Workflows** を実行。 3. **Google Cloud Workflows** のステップ内で **Cloud Run Jobs** を起動し、ジョブを実行。 ### **イベント駆動型(Event-Driven)ジョブの移行** 1. **Railsアプリケーション** から **Google Cloud Workflows** をトリガー。 2. **Google Cloud Workflows** のステップ内で **Cloud Run Jobs** を実行。 また、以下の追加機能を実装しました。 - **同時実行数の制御(スロットリング)** - **workflows_locksテーブル** にスロット情報を保存し、RailsのAPIから同時実行数を返却できるようにすることで、Cloud Run Jobs の同時実行数を制御。 - 同時実行数制限に達しているときは、ttlの時間までGoogle Cloud Workflowsのコールバックを使用して待機し、ttlの時間までHTTPリクエストがない場合はcallbackを破棄してもう一度同時実行数を確認する。 - Workflowsから `POST /workflows/concurrency_count` を叩き、スロットに空きがあるかを判定。 - **スロットが埋まっている場合は、待機中のWorkflowsがFIFOで実行されるように制御。** - **リトライ間隔の制御** - Workflows内で `POST /workflows/retry_intervals` を叩き、リトライ間隔を動的に調整。 - 指数バックオフやランダムなリトライ間隔を活用し、時間経過ごとに適切な間隔を設定。 --- ### エンドポイントとデータベースの説明 | API | 説明 | | --- | --- | | `POST /workflows/callback` | 作成したコールバックURLをDBに保存。 | | `PUT /workflows/release_slot ` | ジョブ完了時にスロットを解放(Workflows の完了時に実行)。 | | `POST /workflows/concurrency_count` | 同時実行数を確認。スロットが空いていれば `workflows_locks` テーブルにレコードを追加。 | #### **workflows_locks テーブル** | カラム | 説明 | | --- | --- | | `id` | プライマリキー | | `execution_id` | Workflows の実行ID | | `lock_key` | スロットリング単位のキー | | `lock_ttl` | スロットの有効期限 | | `status` | `ON` または `OFF`(スロットの状態) | #### **workflows_callback_urls テーブル** | カラム | 説明 | | --- | --- | | `id` | プライマリキー | | `url` | コールバック用のURL | | `workflows_name` | Workflowsの種類 | | `status` | `active` または `inactive`(コールバック待機状態) | --- ## **工夫した点** 1. **Google Cloud Workflows の YAML を変更せずに済む設計** - Workflowsの定義変更を減らすため、Sidekiqのように **Rubyコードで動的に設定** できる仕組みを導入。 - 具体的に、以下のような項目をRubyコードで定義可能にした。 - **リトライ間隔** - **リトライ回数** - **スロットリング(同時実行数、TTL)** - **イベント駆動型 or スケジュール駆動型** - **Cloud Run Jobs で実行する rake タスク名** **(Rubyコード例)** ```ruby class HogeWorkflows < BaseWorkflows workflow_type :event_driven rake_task "workflows:hoge" retry_options({ count: 12 }) retry_interval do (10.minutes + rand((-1.minute)..(1.minute))).to_i end concurrency_options({ limit: 2, ttl: 10.minutes }) end ``` 2. **スロットリングの最適化** - **1,000人以上のユーザーが同時実行する場合でも、待機時間を最小限にするフローを設計。** - WorkflowsとRailsサーバー間のポーリングではなく、**`events.await_callback` を用いたことでコスト削減** を実現。(Workflows の料金はステップ数に応じて課金されるため。) --- ## **比較検討した実行基盤** | サービス | 理由 | | --- | --- | | **Cloud Pub/Sub** | Dead Letter Queue があり、プロセスクラッシュ時のメッセージ損失を防げるが、ACK timeout が **10分** だったため、長時間実行するジョブに不適合。 | | **Cloud Tasks** | Dead Letter Queue がなく、ACK timeout が **30分** だったため、1時間以上のジョブには不適合。 | --- ## **結果** - **OOM Killerによる強制終了がほぼゼロに** - メモリ消費の多いジョブは新基盤、軽量なジョブはSidekiqに分離し、安定性とリソース最適化を実現。 - **ランニングコストの削減** - Sidekiq-Pro の **$150/月** のコストを **約$10/月** に抑えることができた。 --- ## **まとめ** Sidekiqのメモリ制限を回避しつつ、イベント駆動型・スケジュール駆動型のジョブを安定的に実行できる新しい実行基盤を構築しました。 Workflows + Cloud Run Jobs による処理の統合、スロットリング制御、リトライ間隔の動的設定により、**運用コストの削減とジョブ実行の安定化を両立** できました。

プロジェクトカテゴリ
担当工程
経験した職種・役割
あなたが実際に使っていた技術
このプロジェクト詳細は公開されていません

プロジェクトカテゴリ
担当工程
経験した職種・役割
あなたが実際に使っていた技術
このプロジェクト詳細は公開されていません

マネージメント能力

このマネージメント能力は公開されていません

アピール項目


アウトプット

GitHub アカウント
あり
Qiita アカウント
あり
Zenn アカウント
あり
Speaker Deck アカウント
未入力です
SlideShare アカウント
未入力です
特にアピールしたいアウトプット
あり

今後、身につけなければいけないと思っている技術は何ですか?

高トラフィック、大量データを取り扱う際のパフォーマンスを考慮した設計、改善する技術を実務を通して身に付けたい。

あなたが一番パフォーマンスを出せるのはどんな環境ですか?

課題に対して、ある程度裁量を持って意思決定をしても良い環境。

キャラクター

直近で一番やりたいこと
技術を極めたい
好きなスタイル
好きな規模
自信を持って人より秀でていると言える点
学習能力 / 責任感
スキルのタイプ
得意なフェーズ
会社を選ぶ一番の基準
一緒に働く人
やりたくない分野
未入力です
その他の特徴
未入力です
その他のやりたいこと・やりたくないこと
未入力です

やりたい事

手を動かして設計してコードを書きたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
価値あるプロダクトを作り成長させたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
学び続けて技術力でプロダクトに貢献したい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
意義があることや社会に貢献できる仕事がしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
人や計画の調整・マネジメントをしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
レガシーなシステムの保守・運用・改善をしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
企画や仕様を考えるところから関わりたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
業務効率を改善して一緒に働く人のためになりたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
全社横断的な共通基盤作りや強化をしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
組織や文化を作る・成長させる仕事をしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい

基本プロフィール

年齢
今年で20代後半
好きな Text Editor
vscode
希望勤務地
東京都
希望年収
未入力
転職ドラフトスカウトに参加して
企業から指名を受け取ろう!
会員登録をして転職ドラフトスカウトに参加すると、企業から年収付きの指名を受け取ることができます。
会員登録する
ご意見箱

要望、不具合報告、使いづらい点や感想など、お気軽にお寄せください。
いただいたご意見は、今後のサービス向上に活用させていただきます。

なお、このフォームは受付専用のため、返信を行っておりません。
返信を希望する場合はお問い合わせよりご連絡ください。

  • {{error}}
SIGN UPSIGN IN


転職ドラフトを友人や同僚に薦める可能性はどのくらいありますか?