0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RDS Proxy・ElastiCacheについてDVA対策としてまとめてみる

0
Posted at

RDS ProxyとElastiCacheの違い

項目 Amazon RDS Proxy Amazon ElastiCache
主な目的 データベース接続の効率化 データアクセスの高速化
主な機能 接続プーリング・接続の再利用 インメモリキャッシュ
DB接続数 抑制できる場合がある DB接続管理は主目的ではない
DBへのクエリ数 原則としてクエリ自体は削減しない キャッシュヒット時は削減できる
主な用途 Lambdaなどからの接続管理 頻繁に参照するデータの高速取得
データの保存先 バックエンドのRDS/Aurora キャッシュ側のメモリなど
注意点 Session Pinning データの鮮度・キャッシュミス

判断の基本

接続数の悩み → RDS Proxy

読み取り負荷の悩み → ElastiCache

Amazon RDS Proxyとは

Amazon RDS Proxyは、対応するAmazon RDSやAmazon Auroraへのデータベース接続を管理するフルマネージドプロキシサービスです。

アプリケーションとデータベースの間に配置して利用します。

アプリケーション
      │
      ▼
 Amazon RDS Proxy
      │
      ▼
 Amazon RDS / Aurora

主な機能

  • データベース接続のプーリング
  • バックエンド接続の再利用
  • 接続数の急増への対応
  • データベースフェイルオーバー時の接続管理
  • IAM認証との連携
  • Secrets Managerとの連携

RDS Proxyは、多数のクライアント接続が発生するアプリケーションで特に役立ちます。

RDS Proxyを使用する場合

Lambda A ──────┐
Lambda B ──────┤
Lambda C ──────┼──► RDS Proxy ───► Amazon RDS
Lambda D ──────┤
Lambda E ──────┘

RDS Proxyは、アプリケーションからの接続を管理し、バックエンドのデータベース接続を再利用します。

これにより、データベース接続の確立に伴う負荷を抑えられる場合があります。

ただし、RDS Proxyを導入すれば、必ず接続数が大幅に減るわけではありません。

アプリケーションのトランザクションやセッション状態によって、接続の再利用効率は変わります。

コネクションプーリング

コネクションプーリングとは、データベース接続を毎回新規作成するのではなく、一定数の接続を保持して再利用する仕組みです。

プーリングなし

リクエストA
   │
   ├── 接続を作成
   ├── SQLを実行
   └── 接続を切断

リクエストB
   │
   ├── 接続を作成
   ├── SQLを実行
   └── 接続を切断

リクエストごとに接続を作成すると、接続確立に伴う処理が繰り返されます。

プーリングあり

リクエストA ──┐
リクエストB ──┼──► 接続プール ──► Database
リクエストC ──┘

接続を再利用することで、接続確立の負荷を軽減できます。

アプリケーション側の接続プールとの違い

項目 アプリケーション側の接続プール RDS Proxy
管理場所 アプリケーション内部 AWSのマネージドプロキシ
主な管理単位 プロセス・実行環境 複数クライアントからの接続
スケール時 実行環境ごとにプールが増える可能性 プロキシ側でバックエンド接続を管理
運用 アプリケーション側で管理 AWSがプロキシ基盤を管理

Lambdaのように実行環境が増減する仕組みでは、各実行環境に接続プールを用意するだけでは、データベース全体の接続数を十分に抑えられない場合があります。

Connection Multiplexing

RDS Proxyでは、複数のクライアント接続でバックエンドのデータベース接続を効率的に利用する仕組みがあります。

これをConnection Multiplexingと呼びます。

Client A ──┐
Client B ──┼──► RDS Proxy ──► DB Connection 1
Client C ──┘

複数のクライアントが接続していても、すべてのクライアントが常に専用のデータベース接続を保持する必要はありません。

ただし、同時に実行中のSQL処理を、1本のデータベース接続で無制限に処理できるわけではありません。

接続の再利用は、トランザクションの状態や接続の利用状況などに依存します。

Session Pinning

RDS Proxyで重要な概念が、Session Pinning(セッションピン留め) です。

Session Pinningが発生すると、クライアント接続と特定のデータベース接続が結び付けられ、接続の再利用効率が低下する場合があります。

通常の接続再利用

Client A ──┐
Client B ──┼──► RDS Proxy ──► DB接続プール
Client C ──┘

Session Pinningが発生した場合

Client A ──► RDS Proxy ──► DB Connection A
                                 ▲
                                 │
                         Client Aに固定

Session Pinningが発生する理由

データベースのセッション状態に依存する処理では、別の接続へ切り替えると動作が変わる可能性があります。

そのため、RDS Proxyは接続を固定する場合があります。

代表的な要因には、以下があります。

  • セッション変数の変更
  • 一時テーブルの利用
  • 一部のセッション状態に依存するSQL
  • データベースエンジン固有の処理

具体的な条件は、データベースエンジンによって異なります。

長時間トランザクションとの違い

Session Pinningと長時間トランザクションは、どちらも接続再利用の効率に影響しますが、同じ概念ではありません。

項目 Session Pinning 長時間トランザクション
主な原因 セッション状態への依存 トランザクションを長時間保持
接続への影響 クライアントとDB接続が固定される トランザクション中にDB接続を占有する
主な問題 接続再利用効率の低下 接続待ち・ロック競合など
対策の方向性 セッション状態への依存を減らす トランザクションを短くする

例えば、SQLを実行した後にコミットせず、長時間待機するアプリケーションでは、接続を長く占有する可能性があります。

一方、Session Pinningは、トランザクション終了後もセッション状態を維持する必要がある場合などに発生します。

RDS Proxyを利用しているのにDB接続数が多い場合は、Session Pinningと長時間トランザクションの両方を確認します。

RDS ProxyとAWS Lambda

LambdaとRDS Proxyは、データベース接続数が急増する可能性のある構成でよく検討されます。

基本構成

利用者
  │
  ▼
API Gateway
  │
  ▼
AWS Lambda
  │
  ▼
Amazon RDS Proxy
  │
  ▼
Amazon RDS

Lambdaの同時実行数との関係

Lambdaでは、複数のリクエストを並列処理するために実行環境が増える場合があります。

同時実行数:増加
       │
       ▼
Lambda実行環境:増加
       │
       ▼
DB接続要求:増加する可能性
       │
       ▼
RDS Proxyで接続管理

ただし、Lambdaの同時実行数とDB接続数が必ず1対1になるわけではありません。

アプリケーションの接続管理方法によって異なります。

Lambdaで接続を再利用する

Lambdaでは、データベースクライアントなどをハンドラーの外で初期化し、実行環境の再利用時に活用する設計があります。

Pythonの概念例です。

import os
import pymysql

connection = None

def get_connection():
    global connection

    if connection is None or not connection.open:
        connection = pymysql.connect(
            host=os.environ["DB_HOST"],
            user=os.environ["DB_USER"],
            password=os.environ["DB_PASSWORD"],
            database=os.environ["DB_NAME"],
            connect_timeout=5
        )

    return connection

def lambda_handler(event, context):
    conn = get_connection()

    with conn.cursor() as cursor:
        cursor.execute("SELECT 1")
        result = cursor.fetchone()

    return {
        "statusCode": 200,
        "body": str(result)
    }

※ 説明用の簡略化したコードです。実運用では接続切断時の再接続、例外処理、認証情報の安全な管理などが必要です。

また、実行環境の再利用は保証されません。

Lambdaの接続再利用とRDS Proxyは、組み合わせて利用できる別の最適化手段です。

RDS ProxyとIAM認証

RDS Proxyでは、IAM認証を利用する構成があります。

IAM認証では、固定パスワードの代わりに一時的な認証トークンを利用できます。

IAM認証のイメージ

アプリケーション
       │
       ▼
IAM認証トークンを生成
       │
       ▼
Amazon RDS Proxy
       │
       ▼
Amazon RDS / Aurora

RDS Proxyには、クライアント側の認証方法と、プロキシからデータベースへの認証方法があります。

そのため、IAM認証を利用する場合でも、どの区間で利用するかを区別する必要があります。

Secrets Managerとの連携

RDS Proxyでは、Secrets Managerに保存したデータベース認証情報を利用する構成もあります。

アプリケーション
       │
       ▼
RDS Proxy
       │
       ├── Secrets Manager
       │       └── DB認証情報
       │
       ▼
Amazon RDS

RDS ProxyがSecrets Managerのシークレットを利用する場合、適切なIAM権限が必要です。

RDS Proxyとフェイルオーバー

RDS Proxyは、データベースのフェイルオーバー時の接続管理にも役立ちます。

アプリケーション
       │
       ▼
RDS Proxy
       │
       ▼
RDS Primary
       │
       │ 障害発生
       ▼
フェイルオーバー
       │
       ▼
新しいPrimary

アプリケーションはRDS Proxyのエンドポイントを利用するため、バックエンドの切り替えを意識する処理を減らせる場合があります。

ただし、RDS Proxyを利用しても、既存のトランザクションや接続が必ず維持されるわけではありません。

フェイルオーバー中には、実行中のSQLやトランザクションが失敗する可能性があります。

そのため、アプリケーション側では以下を考慮します。

  • 適切なタイムアウト
  • 一時的な接続エラーへの再試行
  • トランザクションの再実行
  • 冪等性の確保

例えば、決済処理などを無条件に再実行すると、二重処理につながる可能性があります。

再試行可能な処理と、重複実行を防ぐ必要がある処理を区別することが重要です。

RDS Proxyの監視

RDS Proxyを利用する場合は、CloudWatchメトリクスなどで状態を確認します。

代表的な監視対象には、以下があります。

監視対象 確認する内容
クライアント接続数 アプリケーションからの接続状況
データベース接続数 バックエンド接続の使用状況
接続借用待ち時間 DB接続を取得するまでの待機
Session Pinning 接続の固定が増えていないか
接続失敗 認証や接続の問題が発生していないか

特に、接続数と接続借用待ち時間を合わせて確認することが重要です。

Amazon ElastiCacheとは

Amazon ElastiCacheは、インメモリデータストアを利用してアプリケーションのパフォーマンスを向上させるマネージドサービスです。

主に、頻繁に参照されるデータを高速に取得するために利用します。

アプリケーション
       │
       ▼
Amazon ElastiCache
       │
       ├── キャッシュヒット
       │       └── データを返す
       │
       └── キャッシュミス
               │
               ▼
           データベース

ElastiCacheのメリット

  • データ取得の高速化
  • データベースの読み取り負荷の軽減
  • アプリケーションのレスポンス改善
  • 頻繁に参照するデータの再利用
  • セッション情報などの一時データ管理

ただし、キャッシュを利用すると、データの整合性や更新タイミングを考慮する必要があります。

Valkey・Redis OSS・Memcachedの違い

ElastiCacheでは、複数のキャッシュエンジンを利用できます。

代表的なものは以下のとおりです。

  • Valkey
  • Redis OSS
  • Memcached

比較表

項目 Valkey Redis OSS Memcached
主な用途 高機能なインメモリデータストア 高機能なインメモリデータストア シンプルな分散キャッシュ
データ構造 複数のデータ型に対応 複数のデータ型に対応 主にキー・バリュー
永続化 構成により利用可能 構成により利用可能 基本的に永続化なし
レプリケーション 対応する構成あり 対応する構成あり Redis系と同等の機能は基本的にない
Pub/Sub 対応 対応 Redis系と同等の機能はない
主な特徴 Redis互換のオープンソースエンジン 多機能なキャッシュエンジン シンプルなキャッシュ処理

※ 利用できる機能は、ElastiCacheのエンジンバージョンやデプロイ構成によって異なります。

Valkey

Valkeyは、Redis OSSと互換性のあるオープンソースのインメモリデータストアです。

代表的な用途は以下のとおりです。

  • キャッシュ
  • セッション管理
  • カウンター
  • ランキング
  • Pub/Sub
  • データ構造を利用した高速処理

Redis OSS

Redis OSSも、キー・バリュー形式を基本としながら、多様なデータ構造を利用できます。

代表的なデータ型には、以下があります。

データ型 用途
String 文字列・数値
Hash オブジェクトに近いデータ
List 順序付きデータ
Set 重複しない要素の集合
Sorted Set スコア付きランキング

Memcached

Memcachedは、シンプルな分散キャッシュとして利用されます。

主な特徴は以下のとおりです。

  • シンプルなキー・バリュー形式
  • マルチスレッド処理
  • キャッシュ用途に特化
  • 永続化を前提としない

複雑なデータ構造や高度な機能が不要な場合に検討できます。

ElastiCacheのデプロイ方式

ElastiCacheでは、エンジンや利用形態に応じて構成を選択します。

Serverless

ElastiCache Serverlessでは、キャッシュ容量や処理量に応じたスケーリングをAWS側で管理します。

アプリケーション
       │
       ▼
ElastiCache Serverless
       │
       ▼
キャッシュデータ

容量設計やノード管理の運用負荷を抑えたい場合に適しています。

ノードベース構成

ノードベース構成では、ノードタイプやノード数などを考慮してキャッシュを構築します。

アプリケーション
       │
       ▼
ElastiCache Cluster
       │
       ├── Node A
       ├── Node B
       └── Node C

必要な容量や処理性能に応じて構成を設計します。

レプリケーションとシャーディング

ValkeyやRedis OSSでは、構成に応じてレプリケーションやシャーディングを利用できます。

仕組み 主な目的
レプリケーション 可用性や読み取り処理の分散
シャーディング データを複数のシャードへ分散

レプリケーションはデータの複製、シャーディングはデータの分割です。

Cache-Aside(Lazy Loading)

Cache-Asideは、アプリケーションが必要に応じてキャッシュを読み書きする方式です。

Lazy Loadingとも呼ばれます。

処理の流れ

アプリケーション
       │
       ▼
キャッシュを確認
       │
       ├── Hit
       │     └── キャッシュから返す
       │
       └── Miss
             │
             ▼
         データベース
             │
             ▼
         キャッシュへ保存
             │
             ▼
           結果を返す

メリット

  • 必要なデータだけをキャッシュできる
  • キャッシュ容量を効率的に利用しやすい
  • アプリケーション側で制御しやすい

デメリット

  • 初回アクセス時はキャッシュミスが発生する
  • 古いデータが残る可能性がある
  • キャッシュが失効した直後にDB負荷が増える場合がある

Write-Through

Write-Throughは、データ更新時にデータベースとキャッシュの両方を更新する方式です。

処理の流れ

アプリケーション
       │
       ▼
データ更新要求
       │
       ▼
DBとキャッシュの更新処理
       │
       ├── Database
       │
       └── Cache

上記は概念図です。

実際の処理順序は、アプリケーションの実装や利用するキャッシュ方式によって異なります。

メリット

  • 更新後のデータをキャッシュへ反映しやすい
  • 読み取り時のキャッシュミスを減らせる場合がある

デメリット

  • 書き込み処理が増える
  • 参照されないデータもキャッシュする可能性がある
  • DB更新とキャッシュ更新の整合性を考慮する必要がある

TTL(Time To Live)

TTLは、キャッシュデータの有効期間を設定する仕組みです。

商品情報をキャッシュ
       │
       ▼
TTL:300秒
       │
       ▼
一定時間後に失効

TTLを設定することで、古いデータが長期間残ることを防ぎやすくなります。

ただし、TTLが短すぎるとキャッシュミスが増え、データベースへのアクセスが増える可能性があります。

逆に、TTLが長すぎると古いデータを返す可能性があります。

TTL 特徴
短い 新しいデータを反映しやすいが、DB負荷が増える可能性
長い キャッシュヒットしやすいが、古いデータが残る可能性

ElastiCacheの監視

ElastiCacheでは、CloudWatchメトリクスなどを利用して状態を確認できます。

代表的な監視項目は以下のとおりです。

監視項目 確認内容
CPU使用率 処理負荷
メモリ使用量 キャッシュ容量の使用状況
キャッシュヒット数 キャッシュから取得できた回数
キャッシュミス数 データが存在しなかった回数
Evictions メモリ不足などによるキーの削除
接続数 クライアント接続の状況
レプリケーション遅延 レプリカへの反映状況

利用できるメトリクスは、エンジンや構成によって異なります。

Evictions

Evictionsは、メモリ使用量などの条件によってキャッシュ内のキーが削除されることです。

キャッシュ容量が不足
        │
        ▼
Eviction Policy
        │
        ▼
一部のキーを削除

Evictionsが増加している場合、キャッシュ容量やデータの保持方針を見直す必要があるかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?