🗂️

【Docker】ElastiCache(Redis)の必要性について勉強しながら検討した

に公開

自己紹介

はじめまして、はると申します。
駆け出しエンジニアとして働き始めて約3ヶ月が経過しました🐣

概要

メールの自動送信機能を実装するためにSidekiq(Redis)を使用しました。
本番環境でElastiCacheを使用したところ、請求金額が高額になってしまい、Redis周りの構成を見直しました😣
Dockerの基礎的な部分も含めて調べたことについてまとめているため、ご存知の方にとっては冗長に感じる表現である場合があります。

環境

  • Docker
  • Ruby 3.2.3
  • Rails 7.1.3
  • インフラ環境(見直し前の状態)

経緯

色々なバックグラウンド処理の方法を調べて、ActiveJob+Sidekiq(Redis) を使うことにしました。
この時の調査とローカルでの実装についてはこちらの記事を参照ください。

https://zenn.dev/lemonade_37/articles/rails-docker-sidekiq

自分はPaaSでしかデプロイしたことが無く、業務でのAWSのインフラ環境は先輩が構築したものでした。
本番環境でもSidekiqやRedisを使う方法を考えたときに、

  • アプリサーバーが落ちた時にキューが削除されては困るから、キューを保持しておくセッションサーバーは別で必要なのではないか?
  • 本番環境でDBは自分で作らないといけないのと同じで、Redisも本番環境用に作らないといけないのでは?
  • 調べていると、ElastiCacheというサービスがあると知る💡

という流れで、しっかり理解しないままElastiCacheを使って実装してしまいました。
ElastiCache導入後1ヶ月ほど経過した段階で、月の料金に数十ドルかかっていることが発覚😇

ElastiCache周りの構成を見直すため、改めて今の構成でわからないところを調査しました。

ボリュームとは何かちゃんと理解できていない

そもそもDockerについても理解が浅く、ローカルではRedisに保持するキューはボリュームで管理していましたが、ボリュームについてちゃんとわかっていませんでした。
  
ボリュームとは、データを永続化できる場所のことです。
コンテナは、Dockerを使うときにdocker compose updocker compose downコマンドで都度作成され、削除されますが、その度にDBのデータも消えてしまっては困ります。
  
DB内のデータ等はボリュームとして持っておくことで、毎回そのデータをコンテナにコピーする形で、同じデータを永続的に扱うことができます。
下記図のようなイメージです。

SidekiqとRedisの違いや関係性

今まで、技術記事等でSidekiq(Redis)と表現していたけどそれぞれの違いについて明確に説明できませんでした😇
  
Redisとは、インメモリデータストアのことです。
Redis内部の説明については、こちらの記事が大変わかりやすかったため、引用させていただきます。2)

https://qiita.com/keinko/items/60c844bcf329bd3f4af8#redisの仕組みのイメージ

Sodekiqとは、キュー管理のツールで、キューを保持したり、今すぐ実行したり、スケジュール管理したりできます。
Sidekiqは、実行待ちのキューを保持しておく場所としてRedisを使用しています。

ElastiCacheを使う場合と使わない場合の違い

本番環境でElastiCacheを使わなければいけないと思い込んでいたが、ローカルではボリュームを使用しているため、本番環境でもボリュームを使う方法ではできないのか?
と先輩エンジニアより助言をいただきました。

ローカル環境

まず、ローカルでのDocker環境はこのようになっています。

本番環境(ElastiCache使用)

次に、見直し前の本番環境はこのようになっています。
今まで本番環境のEC2UbuntuDocker等様々な言葉が出てきて、それぞれの親子関係がわからず混乱していましたが、調べたところ、UbuntuとしてのEC2インスタンスを作成して使用することが多いようです。
(厳密には違うかも知れませんが、EC2そのもの=Ubuntuというように理解しました)

また、ElastiCacheを使用する場合は、Docker内でRedisコンテナを作成したり、キューをボリュームで管理する必要がなくなります。

本番環境(ElastiCacheなし)

ElastiCacheなしだと下記の図のように置き換わります。
EC2内Docker内でredisコンテナを作成し、キューはボリュームで管理します。
この時、docker system prune -aなどのコマンドでボリュームを削除しないように注意します。

結局、ElastiCacheを使用するかしないかどちらがいいのか?

今回においては、ElastiCacheなしで、本番環境でもキューをボリュームで管理することにしました。
今回は、Sidekiqの使用用途が簡単なメール送信のみで、頻度もまだ月1回等少ない状況でした。
また、インフラ環境にそこまでコストをかけられる状況ではありませんでした。
そのため、先輩エンジニアとも相談し、この方法を選択しました。
    
ただし、今後サービス規模が大きくなっていった際には、EC2のサイズを大きくしたり、数を増やすといった対応が必要になります。
その際に、Redisコンテナが2つできてメールが二重送信される可能性があることや、ElastiCacheを使用しRedisをEC2外に外に切り出す方がEC2の容量的にも良い場合もあります。
  
そういったことを念頭に置いた上で、今はElastiCacheなしで運用することとなりました。

まとめ

Dockerやインフラ環境の解像度が少し上がりました。
今回は早めに気づきましたが、わからないまま実装することで、不要なコストが発生してそのまま気づかれず大変なことになってしまう恐れがあるため😇
しっかり1つ1つ理解するよう勉強していこうと思いました🏃‍♀️
ここまで読んでいただきありがとうございました!

参考・引用記事

引用記事

1)さわって理解するDocker入門 第7回 | オブジェクトの広場
2)初心者による初心者のためのRedis解説

参考記事

Discussion