📝

Amazon ElastiCache とは

に公開

Amazon ElastiCache とは - Amazon ElastiCache

Amazon ElastiCache は、クラウドでの分散インメモリデータストアまたはキャッシュ環境のセットアップ、管理、およびスケーリングが簡単になるウェブサービスです。高性能かつスケーラブルで費用対効果の高いキャッシュソリューションを提供します。同時に、分散キャッシュ環境のデプロイと管理に関連する複雑さを排除するのに役立ちます。

AWS が提供するインメモリキャッシュサービスです。

機能概要

  • Valkey, Memcached, Redis OSS プロトコルに準拠
  • アプリケーションにキャッシュやインメモリレイヤーを追加可能
  • サーバーレスキャッシュとノードベースのクラスターのデプロイオプションを提供
  • グローバルデータストア機能によるクロスリージョンレプリカが可能
  • リザーブドノードの購入が可能
  • マルチ AZ での利用ではノードフェイルオーバーが自動的に作動

ユースケース

ElastiCache の一般的なユースケースおよび ElastiCache がどのように役立つか - Amazon ElastiCache
以下のようにマイクロ秒の応答時間が必要なアプリケーションやトラフィックが急増するアプリケーションに最適です。

  • ゲームのリーダーボード
  • リアルタイム入札
  • メッセージング
  • サブスクライブ
  • メディアストリーミング
  • レコメンデーション

インメモリデータベースとインメモリキャッシュ

インメモリデータベースとは? - インメモリ DB の説明 - AWS
インメモリデータベースはディスクベースのデータベースとインメモリキャッシュの中間に位置します。

  • インメモリデータベースは内部メモリを使用してデータを保存する専用のデータベース
  • インメモリデータベース SSD へのアクセスが不要なためレスポンス速度が向上
  • インメモリデータベースは書き込みを永続化
  • インメモリキャッシュは RAM を使用してデータを保存
  • インメモリキャッシュでは書き込みが永続化されない
  • ディスクベースのデータベースはデータを外部ドライブに保存
  • ディスクベースのデータベースはディスクアクセスが必要なためパフォーマンスが低下する可能性がある

AWS が提供するインメモリキャッシュとデータベースサービス

インメモリデータベースとは? - インメモリ DB の説明 - AWS

  • Amazon MemoryDB: インメモリデータベースサービス
  • Amazon ElastiCache: インメモリキャッシュサービス

Redis OSS と Memcached の比較

主に以下の点が異なります。

  • サポートするデータ構造
    • Redis OSS: strings, lists, sets などをサポート
    • Memcached: string, objects をサポート
  • マルチスレッドかどうか
    • Redis OSS: シングルスレッド
    • Memcached: マルチスレッド
  • スナップショット機能の有無
    • Redis OSS: あり
    • Memcached: なし
  • レプリケーション機能の有無
    • Redis OSS: あり
    • Memcached: なし
  • トランザクションのサポート有無
    • Redis OSS: あり
    • Memcached: なし
  • 自動検出機能の有無
    • Redis OSS: なし
    • Memcached: あり
  • フェイルオーバー機能の有無
    • Redis OSS: あり
    • Memcached: なし

詳細な比較については以下の資料もご参照ください。

試してみた

チュートリアルレベルで Redis OSS キャッシュを試してみました。

01. EC2 インスタンスの作成

以下の設定で作成しました。

  • AMI: Amazon Linux 2023
  • キーペア: なし
    • インスタンスコネクトで接続します
  • VPC: デフォルト
  • サブネット: デフォルト
  • セキュリティグループ: デフォルト
    • インバウンド、アウトバンド全開放
  • インスタンスプロファイル: AdministratorAccess 権限を付与したプロファイル

EC2 インスタンスの起動後、以下のコマンドを実行します。

$ sudo yum update -y
$ sudo yum install -y python3-pip
$ sudo pip3 install flask redis

$ cat > app.py << 'EOF'
from flask import Flask, jsonify
import time
import redis
import os
app = Flask(__name__)

redis_host = os.environ.get('REDIS_HOST', None)
if redis_host:
    cache = redis.Redis(
        host=redis_host, 
        port=6379, 
        decode_responses=True,
        ssl=True,
        ssl_cert_reqs=None
    )
else:
    cache = None
@app.route('/')
def index():
    return '''
    <h1>ElastiCache Test Application</h1>
    <p><a href="/without-cache">Without Cache</a> - キャッシュなしでデータ取得</p>
    <p><a href="/with-cache">With Cache</a> - キャッシュありでデータ取得</p>
    '''
@app.route('/without-cache')
def without_cache():
    start = time.time()
    time.sleep(0.5)
    data = {'message': 'Data from database', 'value': 12345}
    elapsed = time.time() - start
    return jsonify({'data': data, 'time': f'{elapsed:.3f}秒', 'source': 'database'})
@app.route('/with-cache')
def with_cache():
    if not cache:
        return jsonify({'error': 'Redis not configured'})
    
    start = time.time()
    try:
        cached_data = cache.get('test_data')
        
        if cached_data:
            elapsed = time.time() - start
            return jsonify({'data': cached_data, 'time': f'{elapsed:.3f}秒', 'source': 'cache'})
        else:
            time.sleep(0.5)
            data = 'Data from database: 12345'
            cache.setex('test_data', 60, data)
            elapsed = time.time() - start
            return jsonify({'data': data, 'time': f'{elapsed:.3f}秒', 'source': 'database (cached)'})
    except Exception as e:
        return jsonify({'error': str(e)})
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)
EOF

02. キャッシュ未使用での動作確認

ElastiCache を使用しない状態でのパフォーマンスを確認します。

$ sudo python3 app.py
 * Serving Flask app 'app'
 * Debug mode: off
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:80
 * Running on http://172.31.17.147:80

手順 1 で作成したEC2 インスタンスのパブリック IPv4 アドレスにブラウザでアクセスして以下のページが表示されることを確認します。

Without Cache をクリックして以下のデータが表示されることを確認します。

{
  "data": {
    "message": "Data from database",
    "value": 12345
  },
  "source": "database",
  "time": "0.501秒"
}

上記のデータ確認後、Ctrl + C でアプリケーションを停止します。

03. ElastiCache Redis OSS キャッシュ

以下の設定で作成しました。

  • モード: Redis OSS
  • デプロイオプション: サーバレス
  • 作成方法: 新しいキャッシュ

上記以外はデフォルト設定で作成しました。


04. EC2 インスタンスから ElastiCache へ接続

手順 01 で作成した EC2 インスタンスで以下のコマンドを実行します。

# エンドポイントの値は手順 03 で作成したElastiCache のエンドポイントに置換
$ export REDIS_HOST=my-test-cache-q64rej.serverless.apne1.cache.amazonaws.com
$ sudo -E python3 app.py
 * Serving Flask app 'app'
 * Debug mode: off
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:80
 * Running on http://172.31.17.147:80

上記コマンド実行後、再度手順 1 で作成したEC2 インスタンスのパブリック IPv4 アドレスにブラウザでアクセスします。
今回は With Cache をクリックして以下のデータが表示されることを確認します。

{
  "data": "Data from database: 12345",
  "source": "database (cached)",
  "time": "0.563秒"
}

3 回ほど上記結果が表示された後に別のブラウザからアクセスしたところ、以下の通りレスポンスが高速化しました。

{
  "data": "Data from database: 12345",
  "source": "cache",
  "time": "0.002秒"
}

以上より、ElastiCache でのキャッシュの効果を確認することができました。

まとめ

今回は Amazon ElastiCache について紹介しました。
どなたかの参考になれば幸いです。

参考資料

Discussion