AWS SAA(Solutions Architect - Associate)対策

ElastiCache

このレッスンでできるようになること

読取負荷をキャッシュに逃がす構成を選び、Redis と Memcached のどちらを使うかを要件語から判断できるようになります。セッション管理がほぼ必ず Redis になる理由も、根拠つきで説明できるようになります。

要件の文から入る

あるメディアサイトが、RDS の前にキャッシュを置いて記事ページの読取負荷を下げたいと考えています。あわせて、Auto Scaling で増減する複数の EC2 にまたがってログイン状態を保持したいという要件があります。現在はアプリケーションサーバーのメモリにセッションを持っているため、スケールインするとログアウトしてしまいます

この文には「読取を逃がす」と「状態を外に出す」という2つの要件が入っています。前者はキャッシュ戦略の話、後者は Redis と Memcached の選択の話です。

キャッシュ戦略

読取をキャッシュに逃がすとき、書き方は主に2つです。

戦略動き向くもの弱点
遅延読み込みキャッシュに無ければデータベースから読み、その結果を書き戻す実際に読まれるものだけが載るので無駄が少ない初回は必ず遅い。更新後に古い値が残りうる
書き込みスルーデータベースを更新するときにキャッシュも同時に更新する常に新しい値が載る読まれないデータも載る。書込が少し重くなる

どちらを選んでも、古い値が残る問題は有効期限を付けて緩和します。「更新されないデータが表示され続ける」という症状が書かれていれば、有効期限の設定か書き込みスルーへの変更が答えになります。

Redis と Memcached の線引き

観点RedisMemcached
扱えるデータ文字列に加えてリスト、セット、ソート済みセット、ハッシュ単純なキーと値だけ
永続化できるできない
レプリケーションできる。読取レプリカとフェイルオーバーを構成できる無い
拡張の方向レプリカ追加とシャーディングノードを増やして水平分割
マルチスレッド主に単一スレッドで処理マルチスレッドで単純処理をさばく
向く用途セッション、ランキング、リアルタイム集計、Pub/Sub単純な結果キャッシュの大量分散

覚え方は単純で、キャッシュが消えて困るなら Redis、消えても困らないなら Memcached です。Memcached はノードが落ちればそのノードのデータは消え、復旧の仕組みがありません。データベースから読み直せる内容ならそれで構いませんが、そこにしか無いものを置くと失われます。

セッション管理が Redis になる理由

セッションはデータベースに元がありません。ノードが落ちて消えると、利用者は強制的にログアウトされます。Redis はレプリケーションとフェイルオーバー、そして永続化を持つので、ノード障害を越えて状態を保てます。Memcached にはこれが無いため、セッションの保存先として設問に出てきたら誤答です。ランキング表示に使うソート済みセットも Redis にしかありません。

要件語から構成への対応表

要件の言い回し選ぶもの
複数サーバーでログイン状態を共有したいElastiCache for Redis
キャッシュが失われても構わない・単純な値だけElastiCache for Memcached
ランキングやスコアの順位を出したいRedis のソート済みセット
キャッシュ自体を落としたくないRedis のレプリケーションとフェイルオーバー
同じ問い合わせが繰り返される遅延読み込み
常に最新の値を返したい書き込みスルーと有効期限
DynamoDB の読取だけを速くしたいDAX

よくある引っ掛け

引っ掛け1、セッション共有に Memcached を選ぶ。 分散はできますが、ノードが落ちるとそのノードのセッションが消えます。「利用者をログアウトさせない」という要件があれば落ちます。

引っ掛け2、DynamoDB の読取高速化に ElastiCache を持ち出す。 動きはしますが、取得と失効をアプリに書き足す必要があります。「アプリの改修を最小限に」という制約が付いていれば DAX が勝ちます。

まとめ

  • 読取負荷を逃がす基本形は、データベースの前にキャッシュを置くこと
  • 遅延読み込みは無駄が少なく、書き込みスルーは鮮度が高い
  • 消えて困るデータは Redis。永続化とレプリケーションがあるのは Redis だけ
  • セッション、ランキング、順位づけは Redis。単純な値の大量キャッシュは Memcached
生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部

復習ミニクイズ

ある企業が、Auto Scaling グループの EC2 上で動く Web アプリを運用しています。ログインセッションを各インスタンスのメモリに保持しているため、スケールイン時に利用者がログアウトしてしまいます。セッションは外部に保存し、キャッシュノードの障害が起きても利用者のログイン状態を維持したいという要件があります。最も適した構成はどれですか。