giftee Tech Blog

ギフティの開発を支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信しています。

NestJS + BullMQ での実装にて Serverless 版 の ElastiCache を使わない理由

こんにちは、ギフティのエンジニアである nishida です。法人向けギフトのプラットフォームに関わるシステム開発をしております。 今回は NestJS を用いた バックエンドアプリケーションにおいて、非同期ジョブを実装する時に Serverless 版の ElastiCache を使わないほうが良い理由について話します。

要約

Serverless 版の ElastiCache では、設定項目の 1 つである maxmemory-policy (メモリ使用量が上限に達した際の挙動) として noeviction (レコードを削除しない) を指定できないため、現時点では Provisioned 版を使いましょう。

プロダクト(giftee Point Base)について

ギフティでは「キモチの循環を促進することで、よりよい関係でつながった社会をつくる」をコーポレートミッションとして、日々 eギフト に関わる事業をおこなっております。 私が携わっている giftee Point Base は、ひとことで申しますと「ポイントサービス」です。 ご導入いただく企業様にとって、最小限の開発工数で充実した商品ラインナップを持つポイントサービスが開始できるようにしております。

giftee Point Base についてもっと知りたい方はこちらをご覧ください。

今回実装したもの

さまざまな実装方法がありますが、今回は Point Base では CSV を用いてポイントを一括付与したいというユースケースに答えるため、非同期処理の機構を実装する必要がありました。 実装方針策定の観点は「チームのスキルセットの観点から慣れ親しんだ Rails の Sidekiq に似た実装であると良い」および「Node 製のバックエンド(NestJS)の王道パターンに乗っかりたい」の 2つです。その方針に照らし合わせると NestJS の公式ドキュメントで公開されている bull というモジュールの後続である BullMQ を使用した実装で進めることとなりました。

ElastiCache で Serverless 版を使わなかった理由

今回この機能のためにインフラを新たに準備するため、S3 や ElastiCache の準備や、worker サーバーのために新たな ECS クラスタを立ち上げました。 ElastiCache は Provisioned 版(すでに定められたコンピューティングリソースを使用するもの)と Serverless 版(状況に応じてコンピューティングリソースを調整してくれるもの)の 2種類がサポートされていますが、当初は Serverless 版を使用する予定でした。

しかし、調査を進めていると Serverless 版の ElastiCache は maxmemory-policy という値の変更をサポートしていない(2024/06/14 現在)ことがわかりました。

maxmemory-policy とは、インメモリストレージである Redis の設定項目であり、メモリの上限に達している時に新たにデータが書き込まれる際どのように振る舞いをするかを決める値です。 ※設定できる値にはいくつかあるのですが、大別すると「エラーを返す」か「ルールに従って削除して保存する」の 2択です。

Redis を一時的なデータキャッシュとして使う分には、自動で不要なレコードを消してくれる方が運用上楽なのですが、Redis をジョブキューとして使う場合は、意図せずキューイングしたジョブが実行されずに消えてしまうと困ります。

そのため、今回設定したい値は「自動で削除せずにエラーを返す」noeviction という値なのですが、現状の Serverless 版の ElastiCache では「一番使われていないものから順に削除」である volatile-lru から変更できないということがわかりました。

総括

本当は運用が楽になりそうな Serverless 版での実装で進めたかったのですが、今回はまだ変更のできないパラメータの重要度が高かったので採用を見送りました。 とはいえ、いつか対応してくれるかもな…とも思っているので定期的にキャッチアップしようと思います。

参考