AWS主催「インメモリデータベースで実現する超高速データベース活用セミナー」での登壇 https://pages.awscloud.com/JAPAN-event-OE-jp-Cat22-Database-20220629-reg-event.html
このスライドは同僚の角田さんとの合作です。
ヘイ株式会社2022/06/29STORES におけるセッションストアへのAmazon MemoryDB for Redis の活用と、移行戦略
View Slide
自己紹介2テクノロジー部門リテール本部SREグループ角田 朋之テクノロジー部門プロダクト基盤本部基盤グループ松本 拓也
会社概要3会社名 ヘイ株式会社設立 2012年3月23日代表取締役社長 佐藤裕介資本金 1億円所在地〒150-0011東京都渋谷区東3丁目16番3号 エフ・ニッセイ恵比寿ビル4階事業内容インターネットビジネスの企画・開発・運営
サービス紹介4お店のデジタル化をまるっとサポートする「STORES プラットフォーム」を展開
サービス紹介5本日お話するシステムお店のデジタル化をまるっとサポートする「STORES プラットフォーム」を展開
サービス紹介6自分でつくれる、本格的なネットショップむずかしい知識や技術いらずで自分だけのネットショップをかんたんに。
お話すること7● セッションストアを移行することになった経緯● セッションストアを移行するための戦略● MemoryDB for Redis を選択した理由● MemoryDB for Redis の導入過程と失敗談
セッションストアを移行することになった経緯
本発表における「セッションストア」9● システムにアクセスしているユーザーに紐づく、ステートフルな情報を保存するところ○ 例■ ユーザーの識別子■ 認証した事実を示すトークン■ CSRF保護用トークン■ 次のリクエスト時に表示する一時的なメッセージ● 今までの STORES では、セッションストアとしてCookieを採用していた
セッションストアとしてのCookie10Pros.● クライアントに保存するのでストレージが不要● 負荷やスケーリングを考えなくて良い● ストレージアクセスのI/Oがなく高速Cons.● 転送量が大きくなる● 扱い方がクライアントの実装に依存● セキュリティ上の懸念がある
セッションストアとしてのCookie今までの STORES では● Cookieの内容を暗号化して一定の安全性を確保● 高速で、スケールするセッションストアとして活用しかし、サービスの成長につれて、徐々にマッチしない部分が出てきた11
セッションストアをCookieから移行する3つの動機121. セキュリティの強化策が限られる2. 特定のセッションを失効させることが難しい3. 将来の複数サービス間でのセッション制御に拡張性を持たせたい
動機1: セキュリティの強化策が限られる13● 暗号化はするものの、情報がクライアント側にあることには変わらない● リプレイ攻撃などの考慮を徹底する必要がある例えばnonceの導入といった工夫も考えられるが…● 別のストレージで保存が必要になる● Cookieの利点である高速さや負荷耐性が損なわれる
動機2: 特定のセッションを失効させることが難しい14● 課題1: Cookieそのものの有効期限は書き換え可能○ 暗号化されたCookie内に独自の日時情報を含むことで対応● 課題2: いざというときに即座に失効させられない○ 課題1の日時情報やログインユーザーに紐づく情報でフィルタして対応● 課題3: ログアウトしてもセッションは失効しない○ Cookieの原理上しかたない。必要に応じて課題2と同様に対応特に課題2,3では、場当たり的な対応になっており運用コストが増大していたQ. フィルタ機能をシステム化すればよいのでは?● 失効させたいセッションを特定する情報を別のストレージで持つ必要性● nonceと同じく、Cookieの利点が損なわれる
動機3: 将来の複数サービス間でのセッション制御に拡張性を持たせたい● システムAとシステムBがあり、IdPとID連携していたとする● 例えば、AでログアウトしたときBでもログアウトさせたいとき、任意のセッションを失効させられる必要がある (※)まだどのような仕様に落ち着くかは不透明だが、何らかの制御を行える状態にしておきたい15システムB(STORES)システムA IdPログアウトしたよログアウトしてねログアウトするぞだが断る※いわゆるシングルサインアウト。OpenID Connect Back-Channel Logout をイメージ
MemoryDB for Redis に格納するセッションのキーペアは(“セッションキー“, “セッションデータ“)任意のセッションを特定するのは、これだけでは難しい● 多くの場合は値で検索したいが、Redisではできない● セッションキーはCookieに格納されていて、逆算もできないユーザーIDなどから、セッションキーを特定したい!補足: 任意のセッションを失効させるための仕組み16
マッピングのイメージ:(“ユーザーID:セッションID”, “セッションキー”)保存先は?● セッションと同じ耐久性は要求されないかも● MemoryDBにするかどうかは検討の余地があるセッションとユーザーのマッピングを作成する17セッションストア引き当て(“セッションキー“, “セッションデータ“)
移行するぞ!18● がんばろう● では、どうやって?移行プロジェクトメンバー
大きく、2つの課題19● どうやって移行するか、移行戦略○ クライアント側に保存されている既存のセッションはどうするか● どのストレージに移行するか○ MemoryDB for Redis を選ぶに至ったのはなぜか
セッションストアの移行戦略
既存のセッションはどうする?21● 既存のセッションを捨てて、新しいセッションからMemoryDBを使う?○ メンテナンスを設けて、その間に切り替える○ ユーザーは一斉にログアウト🥺● ユーザー体験を考えれば、できればセッションを保ったまま移行したい○ どうやって実現する?🤔
ダブルライト (Step 1)22アプリケーション当代Cookie次代MemoryDBWrite Read Write
ダブルライト (Step 2)23アプリケーション当代Cookie次代MemoryDBWrite ReadWrite
ダブルライト (Step 3)24アプリケーション次代MemoryDBReadWrite
より安全に移行するには25移行作業の要求● 問題発生時の影響を小さくしたい● 何かあったときに安全に切り戻したい● 負荷を実績から見積もりながら計画したいなるべく段階的に切り替える方法にしよう
STORESのセッションは2系統ある26ダッシュボードネットショップを運営するオーナーのセッションショップサイトネットショップを利用する顧客のセッション
STORESのセッションは2系統ある27アクセス数は?まずはダッシュボードだけ切り替えてうまく働くことを確認し、サイト全体へと広げていく作戦ダッシュボードショップサイト>>>
Step 0: すべてのセッションはCookieで読み書き28アプリケーション当代CookieWrite Readダッシュボードショップサイト
Step 1: ダッシュボードのセッションをダブルライト、読み込みはCookieから29アプリケーション当代Cookie次代MemoryDBWrite Read Writeダッシュボードショップサイト
Step 1: ダッシュボードのセッションをダブルライト、読み込みはCookieから30アプリケーション当代Cookie次代MemoryDBWrite Readダッシュボードショップサイトダブルライトのロジックの正しさや、MemoryDBの様子を確認
Step 2: すべてのセッションをダブルライト、読み込みはCookieから31アプリケーション当代Cookie次代MemoryDBWrite Read Writeダッシュボードショップサイト ● 負荷は想定範囲内か、次のステップでのReadに耐えうるか● セッションの蓄積やスパイクアクセス時の観察のため、しばらく様子見
Step 3: すべてのセッションをダブルライト、読み込みはMemoryDBから32アプリケーション当代Cookie次代MemoryDBWrite ReadWriteダッシュボードショップサイト 負荷は想定範囲内か、セッションは引き継がれるかを確認
Step 4: すべてのセッションはMemoryDBで読み書き33アプリケーション次代MemoryDBReadWriteダッシュボードショップサイト 移行完了!
STORES サービスの構成
インフラ構成35
MemoryDB for Redis を選択した理由
MemoryDBとは?● Redis互換なインメモリーデータベース○ Redis 6.2+● スケーラブル● フルマネージド● セキュリティー○ VPC○ KMS○ Redis ACL
ElastiCache for Redisとどう違う?● データの高耐久性○ 永続化目的で使える● パフォーマンス○ 書き込みが遅いという噂● セキュリティー○ TLS必須● デフォルトクラスター構成● デフォルトパラメーター
セッションストアの候補
Redis● 既にアプリケーションの他の箇所で使い慣れている● 高速● 機能が必要十分● ダブルライトやクラスターを組むなどしないと可用性が不安○ 逆に言うとクラスターモードやダブルライトで高可用性を実現できる
MongoDB● STORES のメインのDBなのでもちろん使い慣れている● パフォーマンスへの影響が気になる● Redisに比べるとtoo muchか● (定期的にパッチ等のメンテナンスが入る)
DynamoDB● 一部のログを保存するなどで利用はしている● アプリケーションからは利用していないので追加実装が多い○ Gemを増やす○ 使い方を学ぶ● セッションストアなのでHTTPのオーバーヘッドが気になる● Redisに比べるとtoo muchか● ローカル環境の整備をしないと○ DynamoDB Local など
Memcached● 運用が楽● マルチコア使えるので、パフォーマンス良い● 再起動とかも速い● 一切利用していないので追加実装が多い○ Gemを増やす○ 使い方を学ぶ● 耐久性
Redisが良さそう!
Redisのインフラ構成
ElastiCache for Redisで高可用性を実現するには?● クラスターモードでの運用● 自動フェイルオーバーの有効化● Multi AZ● シャーディング● プライマリーで障害が起きるとフラッシュ結構意識することは多い...
MemoryDBなら全部あるよ!● デフォルトクラスターモード● 自動フェイルオーバー● Multi AZ● シャーディングプライマリーの障害でもデータロストしない!新しいサービスが使えて楽しい!
MemoryDB良さそう!
懸念点● パフォーマンスは?○ 書き込みが遅いという噂● ElastiCacheより料金がお高め○ クラスターモードのみなので細かなサイズ調整が難しい場合も○ 大きめのインスタンスしか選べなかった■ 今はt4gも!○ 今回は許容範囲ということで富豪的解決!
MemoryDB for Redis の導入過程と失敗談
調査1 あつめた噂● 書き込みが遅いらしい○ https://aws.amazon.com/jp/blogs/news/introducing-amazon-memorydb-for-redis-a-redis-compatible-durable-in-memory-database-service-jp/> MemoryDB は、データの耐久性とマイクロ秒の読み取り、および一桁ミリ秒の書き込みレイテンシーを提供> ElastiCache は読み取りと書き込みの両方にマイクロ秒のレイテンシーを提供○ https://dev.classmethod.jp/articles/aws-release-durable-redis-amazon-memorydb-for-redis/書き込みが遅いらしい
調査2 AWSの方からも...● > 書き込みレイテンシーについては、 一桁ミリ秒 となります。これは、高い可用性を担保するために、Multi-AZへの書き込みを反映させることによるもので、仕組み上の制約となります。> 一桁ミリ秒では要件が満たされない、かつElastiCache (Redis)の可用性が許容できるならば、ElastiCache (Redis)を使っていくことが推奨されます。> よくある可用性とレイテンシーのトレードオフですね○ 噂通りだけどこの性能差は本当に問題になるのか?試してみよう!
検証● 先ずは書き込みだけ有効にしてリリースしてみる○ 元々Cookieとの両書き期間を設ける予定だったし!○ 幸いCloudWatch MetricsやDatadogのAPMなど可視化は万全!アプリケーション当代Cookie次代MemoryDBWrite Read Write
検証結果1 書き込みのみ● 5%程度処理時間を使っているものの、平均レイテンシーに大きな変化は無し!● スペック上書き込みが遅くてもセッションストア用途なら問題無さそう!リリース5%増量
検証結果2 読み書き両方● 読み書き両方を有効にしてもほぼ影響無し!リリース変化なし!
移行成功!...?
Evictionされない! part 1● ある日Redisのメモリー逼迫アラートが!!!● 急いでクラスターをスケールアウト!● 相当余裕をもってサイジングしたんだけど...● どうしてEvictionされないんだろう?● maxmemory-policy: noeviction がデフォルト!○ ElastiCacheだとvolatile-lruだった
Evictionされない! part 2● ある日Redisのメモリー逼迫アラートが!!!● どうしてEvictionされないんだろう?● 分からないのでAWSサポートの方に泣きつくと...● TTL付いてないキーが一杯ありますよ!○ 我々のアプリケーションの問題だったことが判明m(__)m
STORESのセッションはMemoryDBで元気に稼働中!
まとめ● 高耐久で高速なインメモリーデータベースはMemoryDBはあり!○ お手軽に高耐久なRedisクラスターが使えます!○ 書き込みパフォーマンスについては用途次第で問題にはならない!● AWSサポートの方々の優しさで毎日救われています!