こんにちはCDOの山下です。
今回は、新規サービス開発にあたりRailsのバックグラウンド処理について考えることがあったので記事にしようと思います。
現状のRails環境下でのバックグラウンドジョブ
Railsでバックグラウンドジョブを扱うといえばresqueやsidekiqが有名で多くのサービスでも実運用で使われていると思います。弊社の主力であるANDPADでもサービス開始当初からsidekiqが使われてきましたが、Redisを仲介してジョブを処理するサーバーをアプリケーションサーバーとは別で運用する必要がありサービス規模が大きくなるにつれてインフラ管理コストが負担になってきました。
主な利用用途としては、以下に上げるようなもので、数10msecで終わるようなものから数時間単位で終わるものまで様々な処理がバックグラウンドジョブに放り込まれています。
主な用途
- リアルタイム通信連携(10msec~1sec)
- 外部連携(10msec~1sec)
- 画像処理、加工(100msec~10sec)
- インポート、エクスポート系処理(1min~6h)
また弊社では、新規で開発するサービスに関してはマイクロサービスとしてkubernetes(k8s)のクラスタ環境にアプリケーションをデプロイする機会が増えてきましたが、バックグラウンドジョブを今までのsidekiqサーバーに相乗りしていくと加速度的に負担が増えていく状態になるため別の方法を検討し始めました。
SQS + Lambdaでバックグラウンドジョブを処理する
2018年6月よりAWS LambdaのイベントリソースがSQSに対応したことからSQSにenqueueしたイベントからLambdaを起動して処理をすることが可能になりました。Lambdaの実行時間も最大15分に拡大していることからインポート、エクスポート系の処理以外はLambdaに移行しても問題なさそうな雰囲気です。弊社では、新規サービスと既存サービスで切り出しやすそうなところから徐々にSQS + Lambdaの構成にバックグラウンドの処理を移行し始めています。serverless frameworkを採用することでLambda関数のデプロイを簡易に実行できるようになっています。
SQS + Lambda構成のメリット・デメリット
SQS + Lambda構成のメリットとデメリットを上げておきます。Railsエンジニアにとっては開発負担が増えるのでより良い方法はないかと色々模索しましたが、サーバー管理の必要のないスケーラブルな構成はとても魅力的だなと感じています。また、Lambdaの実行時間制限があるので既存のバックグラウンド処理の全てを網羅できなかったのが悩ましいところです。少し時間のかかる処理(インポート、エクスポート系の処理)は別の方式を模索中です。
メリット
- スケーラブル
- 従量課金になるのでコストが抑えられる
- 言語の選択肢が広がる
デメリット
- Railsでまるっと管理できなくなる
- 簡易にアプリ側の資産を使えなくなる
- Lambdaの実行時間制限(15分)があるので全てを解決できない
まとめ
Railsのバックグラウンド処理の作り方としては、世の中にsidekiqやresqueなどの定番的なものはあるもののインフラ的な側面ではコンテナ化やサーバーレスなどRailsの枠を超えた選択肢もありなかなか悩ましいなと思ってます。k8sクラスタの中にバックグラウンドを処理するコンテナを抱え込む方法も模索はしていましたが、管理コストが上がるので結局断念しました(より良い方法があるよって方は是非情報交換しましょう)。今回この方式を採用するデメリットとしては、今までRailsの中で書けていたバックグラウンドの処理をLambda実行用に別に記述しなければいけなくなったことがあります。ただ、言語の制限なく実行できるという面ではメリットにもなっています。Railsエンジニアとしては手間が増えることも事実ですが、SQSやLambdaをうまく使うことで関心が分離されスケーラブルな構成に少しずつできていければと思っています。