こんにちは、ギフティのエンジニアである 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 版での実装で進めたかったのですが、今回はまだ変更のできないパラメータの重要度が高かったので採用を見送りました。 とはいえ、いつか対応してくれるかもな…とも思っているので定期的にキャッチアップしようと思います。