AWS学びなおし(+TF)_ElastiCache (Redis)
ElastiCache (Redis) とは?
AWS ElastiCache は、クラウド上でフルマネージドなインメモリデータストアサービスです。Redis と Memcached の2つのエンジンを選択できますが、ここでは Redis に焦点を当てて解説します。
Redis は、Remote Dictionary Server の略で、インメモリ型のキーバリューストア(KVS)です。データをメモリ上に保持することで、非常に高速な読み書き性能を発揮します。ElastiCache for Redis は、この Redis をAWSのマネージドサービスとして提供することで、ユーザーはRedisの構築、運用、保守といった煩雑な作業から解放され、アプリケーション開発に集中できます。
ElastiCache (Redis) の主な特徴
- 高速性: インメモリデータストアであるため、ディスクI/Oのボトルネックがなく、非常に高速なデータアクセスが可能です。ミリ秒、マイクロ秒単位の低レイテンシを実現できます。
- 多様なデータ構造: 単純な文字列だけでなく、リスト、セット、ハッシュ、ソート済みセットなど、様々なデータ構造をサポートしています。これにより、キャッシュ用途だけでなく、セッションストア、メッセージキュー、リアルタイム分析など、幅広い用途に活用できます。
- 高い可用性: マルチAZ構成や自動フェイルオーバー機能により、可用性の高いシステムを構築できます。ノード障害時にも自動的にレプリカに切り替わり、サービス停止時間を最小限に抑えられます。
- スケーラビリティ: 水平方向へのスケールアウト(ノード数増加)や、垂直方向へのスケールアップ(インスタンスタイプ変更)が容易に行えます。アプリケーションの負荷変動に合わせて柔軟にリソースを調整できます。
- 永続性: Redis はデフォルトではインメモリデータストアですが、AOF (Append Only File) や RDB (Redis DataBase) などの永続化オプションを利用することで、データの永続性を確保できます。
- 豊富な機能: Pub/Sub、Luaスクリプティング、トランザクションなど、高度な機能をサポートしており、複雑な要件にも対応できます。
- AWS サービスとの連携: VPC、IAM、CloudWatch、CloudTrail など、他のAWSサービスとの連携が容易です。セキュリティ、監視、ログ管理などがAWSのエコシステムの中で完結できます。
ElastiCache (Redis) のユースケース
-
キャッシュ:
- データベースキャッシュ: 頻繁にアクセスされるデータを Redis にキャッシュすることで、データベースへの負荷を軽減し、アプリケーションの応答速度を向上させます。
- セッションキャッシュ: Webアプリケーションのセッション情報を Redis に保存することで、ステートレスなアプリケーションアーキテクチャを実現し、スケーラビリティを高めます。
- APIキャッシュ: API レスポンスを Redis にキャッシュすることで、API サーバーの負荷を軽減し、API の応答速度を向上させます。
- セッションストア: 大量の同時接続を処理する必要があるWebアプリケーションやモバイルアプリケーションのセッション管理に最適です。
- リアルタイム分析: 高速な書き込み性能とデータ構造を活用して、リアルタイムのデータ分析や集計処理に利用できます。
- リーダーボード、ランキング: ソート済みセットを利用して、リアルタイムのランキングやリーダーボードを構築できます。
- メッセージキュー、Pub/Sub: Redis の Pub/Sub 機能やリスト型データ構造を利用して、軽量なメッセージキューやリアルタイム通知システムを構築できます。
- 地理空間データ: Redis Geo 機能を利用して、地理空間データのインデックス作成や検索処理を行えます。
ElastiCache (Redis) の料金体系
ElastiCache (Redis) の料金は、主に以下の要素によって決まります。
- インスタンスタイプ: ノードの種類とサイズによって料金が異なります。メモリ容量、CPU性能、ネットワーク性能などを考慮して適切なインスタンスタイプを選択する必要があります。
- データ転送量: リージョン内外へのデータ転送量に応じて料金が発生します。
- ストレージ: AOF 永続化を使用する場合、ストレージ料金が発生します。
- バックアップ: スナップショットの保存容量に応じて料金が発生します。
詳細な料金については、AWS ElastiCache の料金ページを参照してください。
【実務レベルの内容と重要事項】
実務で考慮すべき重要事項
-
インスタンスタイプの選定:
- ワークロード: アプリケーションの負荷特性(読み込み/書き込み比率、データサイズ、同時接続数など)を正確に把握し、適切なインスタンスタイプを選定する必要があります。
- メモリ容量: キャッシュしたいデータサイズ、セッション情報量、その他Redisで扱うデータ量を考慮して、十分なメモリ容量を持つインスタンスタイプを選択する必要があります。メモリ不足はパフォーマンス劣化に直結します。
- CPU性能: CPU負荷が高いワークロード(複雑なデータ構造の操作、Luaスクリプト実行など)の場合は、CPU性能の高いインスタンスタイプを選択する必要があります。
- ネットワーク性能: 高スループット、低レイテンシが求められる場合は、ネットワーク最適化されたインスタンスタイプ(例: Graviton ベースのインスタンス)を検討する必要があります。
- コスト: パフォーマンス要件とコストのバランスを考慮して、最適なインスタンスタイプを選定する必要があります。
-
キャッシュ戦略:
- Cache-Aside (Lazy Loading): アプリケーションがキャッシュにデータが存在するか確認し、存在しない場合はデータソースから取得してキャッシュに格納する戦略。最も一般的なキャッシュ戦略で、キャッシュミス時のレイテンシが増加する可能性があります。
- Write-Through: データをキャッシュに書き込むと同時にデータソースにも書き込む戦略。データの一貫性を保ちやすいですが、書き込みレイテンシが増加する可能性があります。
- Write-Back (Write-Behind): データをキャッシュに書き込むだけで、データソースへの書き込みは遅延させる戦略。書き込みレイテンシを低減できますが、データの一貫性が損なわれるリスクがあります。
- アプリケーションの要件に合わせて適切なキャッシュ戦略を選択し、実装する必要があります。
-
可用性設計:
- マルチAZ構成: 可用性を高めるために、必ずマルチAZ構成を有効にしましょう。プライマリノードに障害が発生した場合、自動的にスタンバイノードにフェイルオーバーし、サービス継続性を確保できます。
- リードレプリカ: 読み込み負荷分散、読み込み性能向上、災害対策のためにリードレプリカを導入することを検討しましょう。リードレプリカはプライマリノードの読み込み負荷を分散し、読み込み処理のスケールアウトを実現します。また、プライマリノードとは異なるAZに配置することで、災害対策としても有効です。
- Redis Cluster: 大規模データ、高スループット、高可用性が求められる場合は、Redis Cluster を検討しましょう。Redis Cluster はデータを複数のノードに分散(シャーディング)することで、水平方向へのスケールアウトを実現します。
-
セキュリティ対策:
- VPC 内へのデプロイ: ElastiCache (Redis) は必ず VPC 内にデプロイし、インターネットからの直接アクセスを遮断しましょう。
- セキュリティグループ: セキュリティグループを設定し、Redis ノードへのアクセスを許可する送信元を制限しましょう。アプリケーションサーバーからのアクセスのみを許可するように設定するのが一般的です。
- IAMロール: アプリケーションサーバーに適切なIAMロールを付与し、ElastiCache (Redis) へのアクセス権限を制御しましょう。最小権限の原則に基づいて、必要な権限のみを付与するようにしましょう。
- Redis AUTH (パスワード認証): Redis AUTH を有効にし、Redis へのアクセスにパスワード認証を必須にしましょう。
- TLS 暗号化: データ転送時の暗号化を有効にしましょう。ElastiCache (Redis) は、ノード間およびクライアント-ノード間の通信を TLS で暗号化できます。
-
監視とモニタリング:
- CloudWatch メトリクス: CloudWatch メトリクスを監視し、Redis のパフォーマンスやヘルス状態を常に把握しましょう。CPU使用率、メモリ使用率、接続数、キャッシュヒット率、レイテンシなどの重要なメトリクスを監視し、異常を早期に検知できるようにアラートを設定しましょう。
- Redis INFO コマンド: Redis INFO コマンドで詳細な情報を取得し、パフォーマンス分析やトラブルシューティングに役立てましょう。
- ログ: Slowlog などを活用し、パフォーマンスボトルネックの特定やチューニングに役立てましょう。
-
バックアップとリストア:
- 自動バックアップ: 自動バックアップを有効にし、定期的にスナップショットを取得するようにしましょう。
- 手動バックアップ: 必要に応じて手動バックアップを取得し、重要な時点のデータを保護しましょう。
- リストア: バックアップからのリストア手順を事前に確認しておきましょう。障害発生時の迅速な復旧に備えるために、リストア手順を定期的にテストすることも重要です。
-
運用とメンテナンス:
- パッチ適用とバージョンアップ: 定期的にパッチを適用し、Redis エンジンを最新バージョンに保つようにしましょう。セキュリティ脆弱性対策やパフォーマンス改善のために重要です。
- メンテナンスウィンドウ: メンテナンスウィンドウを設定し、メンテナンス作業によるサービス影響を最小限に抑えましょう。
- スケーリング: 負荷変動に合わせて、適切にスケールアップ/スケールアウトを行いましょう。
- パラメータグループ: パラメータグループを適切に設定し、Redis の動作をチューニングしましょう。
パフォーマンスチューニングのポイント
- 適切なデータ構造の選択: 用途に最適なデータ構造を選択することで、メモリ効率とパフォーマンスを向上させることができます。
- キーの設計: キーの命名規則を統一し、効率的なキー検索ができるように設計しましょう。プレフィックスなどを活用してキーをグルーピングすると管理しやすくなります。
- コマンドの最適化: 時間計算量 (O(N) など) の大きいコマンドの使用は避け、効率的なコマンドを使用するように心がけましょう。
- クライアント側のチューニング: クライアントライブラリの設定(接続プーリング、タイムアウト設定など)を最適化することで、パフォーマンスを向上させることができます。
- ネットワークの最適化: アプリケーションサーバーと ElastiCache (Redis) ノード間のネットワークレイテンシを最小限に抑えるように、AZ配置などを検討しましょう。
【実務でどの程度使用されるのか】
ElastiCache (Redis) は、実務で 非常に広く利用されています。Webアプリケーション、モバイルアプリケーション、APIバックエンドなど、様々なシステムでキャッシュ用途を中心に活用されています。
利用頻度が高い理由
- 汎用性の高さ: キャッシュ用途だけでなく、セッションストア、メッセージキュー、リアルタイム分析など、幅広い用途に利用できるため、様々なシステム要件に対応できます。
- 高いパフォーマンス: インメモリデータストアであるため、高速なデータアクセスが求められるシステムに最適です。特に、低レイテンシが重要なWebアプリケーションやAPIバックエンドでは、パフォーマンス向上のための重要な要素となります。
- マネージドサービス: AWS がフルマネージドで提供しているため、ユーザーはRedisの運用・保守に手間をかけることなく、アプリケーション開発に集中できます。
- AWS エコシステムとの親和性: 他のAWSサービスとの連携が容易であり、AWS環境でシステム構築を行う際に自然な選択肢となります。
具体的な利用例
- 大規模ECサイト: 商品詳細ページ、カテゴリページ、検索結果などのキャッシュ、カート情報、セッション情報などに利用されています。
- ソーシャルメディア: タイムライン、フィード、ユーザー情報、リアルタイムランキングなどに利用されています。
- オンラインゲーム: プレイヤーのセッション情報、ランキング、リアルタイム対戦のマッチングなどに利用されています。
- 金融システム: 取引データキャッシュ、レート情報キャッシュ、リアルタイムリスク管理などに利用されています。
- IoTプラットフォーム: デバイスデータのキャッシュ、コマンドキュー、リアルタイムアラートなどに利用されています。
上記以外にも、様々な業界、様々な規模のシステムで ElastiCache (Redis) が活用されており、クラウド環境におけるデータキャッシュ、高速データ処理基盤として デファクトスタンダード と言える存在です。
【terraformのコードで記述する場合の基本的内容と実務レベルの内容】
Terraform コード (基本)
基本的な ElastiCache (Redis) クラスターを作成する Terraform コード例です。
resource "aws_elasticache_cluster" "example" {
cluster_id = "example-redis"
engine = "redis"
node_type = "cache.t3.micro" # 適切なインスタンスタイプを選択
num_cache_nodes = 1
engine_version = "6.x" # 適切な Redis バージョンを選択
parameter_group_name = "default.redis6.x"
subnet_group_name = aws_elasticache_subnet_group.example.name
security_group_ids = [aws_security_group.example.id]
tags = {
Name = "example-redis-cluster"
Environment = "dev"
}
}
resource "aws_elasticache_subnet_group" "example" {
name = "example-redis-subnet-group"
subnet_ids = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id] # VPC内のプライベートサブネットを指定
}
resource "aws_security_group" "example" {
name = "example-redis-sg"
description = "Allow access to Redis cluster"
vpc_id = aws_vpc.example.id
ingress {
from_port = 6379 # Redis デフォルトポート
to_port = 6379
protocol = "tcp"
cidr_blocks = [aws_vpc.example.cidr_block] # VPC CIDR からのアクセスを許可 (必要に応じて調整)
}
}
Terraform コード (実務レベル)
実務で利用することを想定した、より高度な設定を含む Terraform コード例です。
resource "aws_elasticache_replication_group" "example" {
replication_group_id = "example-redis-rg"
replication_group_description = "Example Redis Replication Group"
engine = "redis"
node_type = "cache.m5.large" # ワークロードに合わせて適切なインスタンスタイプを選択
num_node_groups = 1 # Redis Cluster の場合はノードグループ数を指定
replicas_per_node_group = 1 # リードレプリカ数 (マルチAZ構成の場合は1以上)
engine_version = "6.x"
parameter_group_name = aws_elasticache_parameter_group.example.name
subnet_group_name = aws_elasticache_subnet_group.example.name
security_group_ids = [aws_security_group.example.id]
automatic_failover_enabled = true # マルチAZ構成を有効化
multi_az_enabled = true # マルチAZ構成を有効化 (推奨)
transit_encryption_enabled = true # データ転送時の暗号化を有効化 (推奨)
at_rest_encryption_enabled = true # 保存時の暗号化を有効化 (機密データを取り扱う場合は必須)
auth_token_enabled = true # Redis AUTH を有効化 (推奨)
auth_token = "your-secure-password" # 強固なパスワードを設定 (Secrets Manager などで管理するのが望ましい)
maintenance_window = "Mon:03:00-Mon:04:00" # メンテナンスウィンドウを設定 (サービス影響を考慮して適切な時間帯を選択)
snapshot_window = "05:00-06:00" # スナップショットウィンドウを設定
snapshot_retention_limit = 7 # スナップショットの保持期間 (日)
apply_immediately = true # 設定変更を即時適用 (メンテナンスウィンドウ外でも適用する場合)
tags = {
Name = "example-redis-replication-group"
Environment = "prod"
ManagedBy = "Terraform"
}
}
resource "aws_elasticache_parameter_group" "example" {
name = "example-redis-parameter-group"
family = "redis6.x" # 使用する Redis エンジンバージョンに合わせたパラメータグループファミリーを指定
description = "Custom Redis Parameter Group"
parameter {
name = "maxmemory-policy"
value = "allkeys-lru" # メモリポリシーを設定 (例: LRU: Least Recently Used)
}
parameter {
name = "tcp-keepalive"
value = 60 # TCP Keepalive 時間を設定 (秒)
}
}
resource "aws_elasticache_subnet_group" "example" {
name = "example-redis-subnet-group"
subnet_ids = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id, aws_subnet.private_subnet_3.id] # 複数のAZにまたがるプライベートサブネットを指定 (可用性向上)
}
resource "aws_security_group" "example" {
name = "example-redis-sg"
description = "Allow access to Redis cluster from application servers"
vpc_id = aws_vpc.example.id
ingress {
from_port = 6379
to_port = 6379
protocol = "tcp"
security_groups = [aws_security_group.app_server_sg.id] # アプリケーションサーバーのセキュリティグループからのアクセスのみ許可
}
egress { # アウトバウンドルールも明示的に設定 (セキュリティ強化)
from_port = 0
to_port = 0
protocol = "-1" # すべてのプロトコル
cidr_blocks = ["0.0.0.0/0"] # 全ての送信先を許可 (必要に応じて制限)
}
}
実務レベルのTerraformコードのポイント
-
Replication Group の利用: 可用性、スケーラビリティ、管理性を考慮し、
aws_elasticache_replication_group
リソースを利用して Redis クラスターを構築するのが一般的です。 -
マルチAZ構成:
multi_az_enabled = true
を設定し、マルチAZ構成を有効にすることで、可用性を高めます。 -
セキュリティ対策:
-
transit_encryption_enabled = true
,at_rest_encryption_enabled = true
でデータ暗号化を有効化 -
auth_token_enabled = true
で Redis AUTH を有効化 - セキュリティグループでアクセス元を制限
-
-
パラメータグループのカスタマイズ:
aws_elasticache_parameter_group
リソースでパラメータグループをカスタマイズし、ワークロードに合わせて Redis の動作をチューニングします。 -
メンテナンスウィンドウ、スナップショット設定:
maintenance_window
,snapshot_window
,snapshot_retention_limit
などを適切に設定し、運用性を向上させます。 -
タグ設定:
tags
を設定し、リソース管理、コスト管理を容易にします。 -
Secrets Manager連携:
auth_token
などの機密情報は、Terraformコードに直接記述するのではなく、AWS Secrets Manager などのシークレット管理サービスで管理し、Terraform から参照するようにするのがセキュリティ上のベストプラクティスです。(コード例では簡略化のため直接記述しています) - モジュール化: 複雑なシステムの場合は、Terraform モジュールを作成し、コードの再利用性、可読性、保守性を高めることを検討しましょう。
上記はあくまで基本的な例であり、実際のシステム要件に合わせて、インスタンスタイプ、Redis バージョン、パラメータ設定、セキュリティ設定などを適切に調整する必要があります。また、IaC (Infrastructure as Code) のベストプラクティスに従い、Terraform コードを適切に管理、バージョン管理していくことが重要です。
Discussion