Slide 1

Slide 1 text

ヘイ株式会社 2022/06/29 STORES におけるセッションストアへの Amazon MemoryDB for Redis の活用と、 移行戦略

Slide 2

Slide 2 text

自己紹介 2 テクノロジー部門 リテール本部 SREグループ 角田 朋之 テクノロジー部門 プロダクト基盤本部 基盤グループ 松本 拓也

Slide 3

Slide 3 text

会社概要 3 会社名 ヘイ株式会社 設立 2012年3月23日 代表取締役社長 佐藤裕介 資本金 1億円 所在地 〒150-0011 東京都渋谷区東3丁目16番3号 エフ・ ニッセイ恵比寿ビル4階 事業内容 インターネットビジネスの企画・開発・ 運営

Slide 4

Slide 4 text

サービス紹介 4 お店のデジタル化をまるっとサポートする 「STORES プラットフォーム」を展開

Slide 5

Slide 5 text

サービス紹介 5 本日お話するシステム お店のデジタル化をまるっとサポートする 「STORES プラットフォーム」を展開

Slide 6

Slide 6 text

サービス紹介 6 自分でつくれる、 本格的なネットショップ むずかしい知識や技術いらずで 自分だけのネットショップをかんたんに。

Slide 7

Slide 7 text

お話すること 7 ● セッションストアを移行することになった経緯 ● セッションストアを移行するための戦略 ● MemoryDB for Redis を選択した理由 ● MemoryDB for Redis の導入過程と失敗談

Slide 8

Slide 8 text

セッションストアを移行することになった経緯

Slide 9

Slide 9 text

本発表における「セッションストア」 9 ● システムにアクセスしているユーザーに紐づく、ステートフルな情報を保存す るところ ○ 例 ■ ユーザーの識別子 ■ 認証した事実を示すトークン ■ CSRF保護用トークン ■ 次のリクエスト時に表示する一時的なメッセージ ● 今までの STORES では、セッションストアとしてCookieを採用していた

Slide 10

Slide 10 text

セッションストアとしてのCookie 10 Pros. ● クライアントに保存するので ストレージが不要 ● 負荷やスケーリングを考えなくて 良い ● ストレージアクセスのI/Oがなく 高速 Cons. ● 転送量が大きくなる ● 扱い方がクライアントの実装に依存 ● セキュリティ上の懸念がある

Slide 11

Slide 11 text

セッションストアとしてのCookie 今までの STORES では ● Cookieの内容を暗号化して一定の安全性を確保 ● 高速で、スケールするセッションストアとして活用 しかし、サービスの成長につれて、徐々にマッチしない部分が出てきた 11

Slide 12

Slide 12 text

セッションストアをCookieから移行する3つの動機 12 1. セキュリティの強化策が限られる 2. 特定のセッションを失効させることが難しい 3. 将来の複数サービス間でのセッション制御に拡張性を持たせたい

Slide 13

Slide 13 text

動機1: セキュリティの強化策が限られる 13 ● 暗号化はするものの、情報がクライアント側にあることには変わらない ● リプレイ攻撃などの考慮を徹底する必要がある 例えばnonceの導入といった工夫も考えられるが… ● 別のストレージで保存が必要になる ● Cookieの利点である高速さや負荷耐性が損なわれる

Slide 14

Slide 14 text

動機2: 特定のセッションを失効させることが難しい 14 ● 課題1: Cookieそのものの有効期限は書き換え可能 ○ 暗号化されたCookie内に独自の日時情報を含むことで対応 ● 課題2: いざというときに即座に失効させられない ○ 課題1の日時情報やログインユーザーに紐づく情報でフィルタして対応 ● 課題3: ログアウトしてもセッションは失効しない ○ Cookieの原理上しかたない。必要に応じて課題2と同様に対応 特に課題2,3では、場当たり的な対応になっており運用コストが増大していた Q. フィルタ機能をシステム化すればよいのでは? ● 失効させたいセッションを特定する情報を別のストレージで持つ必要性 ● nonceと同じく、Cookieの利点が損なわれる

Slide 15

Slide 15 text

動機3: 将来の複数サービス間でのセッション制御に拡張性を持たせたい ● システムAとシステムBがあり、IdPとID連携していたとする ● 例えば、AでログアウトしたときBでもログアウトさせたいとき、任意のセッ ションを失効させられる必要がある (※) まだどのような仕様に落ち着くかは不透明だが、何らかの制御を行える状態にして おきたい 15 システムB (STORES) システムA IdP ログアウト したよ ログアウト してね ログアウト するぞ だが断る ※いわゆるシングルサインアウト。OpenID Connect Back-Channel Logout をイメージ

Slide 16

Slide 16 text

MemoryDB for Redis に格納するセッションのキーペアは (“セッションキー“, “セッションデータ“) 任意のセッションを特定するのは、これだけでは難しい ● 多くの場合は値で検索したいが、Redisではできない ● セッションキーはCookieに格納されていて、逆算もできない ユーザーIDなどから、セッションキーを特定したい! 補足: 任意のセッションを失効させるための仕組み 16

Slide 17

Slide 17 text

マッピングのイメージ: (“ユーザーID:セッションID”, “セッションキー”) 保存先は? ● セッションと同じ耐久性は要求されないかも ● MemoryDBにするかどうかは検討の余地がある セッションとユーザーのマッピングを作成する 17 セッションストア 引き当て (“セッションキー“, “セッションデータ“)

Slide 18

Slide 18 text

移行するぞ! 18 ● がんばろう ● では、どうやって? 移行プロジェクトメンバー

Slide 19

Slide 19 text

大きく、2つの課題 19 ● どうやって移行するか、移行戦略 ○ クライアント側に保存されている既存のセッションはどうするか ● どのストレージに移行するか ○ MemoryDB for Redis を選ぶに至ったのはなぜか

Slide 20

Slide 20 text

セッションストアの移行戦略

Slide 21

Slide 21 text

既存のセッションはどうする? 21 ● 既存のセッションを捨てて、新しいセッションからMemoryDBを使う? ○ メンテナンスを設けて、その間に切り替える ○ ユーザーは一斉にログアウト🥺 ● ユーザー体験を考えれば、できればセッションを保ったまま移行したい ○ どうやって実現する?🤔

Slide 22

Slide 22 text

ダブルライト (Step 1) 22 アプリケーション 当代 Cookie 次代 MemoryDB Write Read Write

Slide 23

Slide 23 text

ダブルライト (Step 2) 23 アプリケーション 当代 Cookie 次代 MemoryDB Write Read Write

Slide 24

Slide 24 text

ダブルライト (Step 3) 24 アプリケーション 次代 MemoryDB Read Write

Slide 25

Slide 25 text

より安全に移行するには 25 移行作業の要求 ● 問題発生時の影響を小さくしたい ● 何かあったときに安全に切り戻したい ● 負荷を実績から見積もりながら計画したい なるべく段階的に切り替える方法にしよう

Slide 26

Slide 26 text

STORESのセッションは2系統ある 26 ダッシュボード ネットショップを運営するオーナーのセッション ショップサイト ネットショップを利用する顧客のセッション

Slide 27

Slide 27 text

STORESのセッションは2系統ある 27 アクセス数は? まずはダッシュボードだけ切り替えてうまく働くことを確認し、サイト全体へと広 げていく作戦 ダッシュボード ショップサイト >>>

Slide 28

Slide 28 text

Step 0: すべてのセッションはCookieで読み書き 28 アプリケーション 当代 Cookie Write Read ダッシュボード ショップサイト

Slide 29

Slide 29 text

Step 1: ダッシュボードのセッションをダブルライト、読み込みはCookieから 29 アプリケーション 当代 Cookie 次代 MemoryDB Write Read Write ダッシュボード ショップサイト

Slide 30

Slide 30 text

Step 1: ダッシュボードのセッションをダブルライト、読み込みはCookieから 30 アプリケーション 当代 Cookie 次代 MemoryDB Write Read ダッシュボード ショップサイト ダブルライトのロジックの正しさや、 MemoryDBの様子を確認

Slide 31

Slide 31 text

Step 2: すべてのセッションをダブルライト、読み込みはCookieから 31 アプリケーション 当代 Cookie 次代 MemoryDB Write Read Write ダッシュボード ショップサイト ● 負荷は想定範囲内か、次のステップでのReadに耐えうるか ● セッションの蓄積やスパイクアクセス時の観察のため、しば らく様子見

Slide 32

Slide 32 text

Step 3: すべてのセッションをダブルライト、読み込みはMemoryDBから 32 アプリケーション 当代 Cookie 次代 MemoryDB Write Read Write ダッシュボード ショップサイト 負荷は想定範囲内か、セッションは引き継が れるかを確認

Slide 33

Slide 33 text

Step 4: すべてのセッションはMemoryDBで読み書き 33 アプリケーション 次代 MemoryDB Read Write ダッシュボード ショップサイト 移行完了!

Slide 34

Slide 34 text

STORES サービスの構成

Slide 35

Slide 35 text

インフラ構成 35

Slide 36

Slide 36 text

MemoryDB for Redis を選択した理由

Slide 37

Slide 37 text

MemoryDBとは? ● Redis互換なインメモリーデータベース ○ Redis 6.2+ ● スケーラブル ● フルマネージド ● セキュリティー ○ VPC ○ KMS ○ Redis ACL

Slide 38

Slide 38 text

ElastiCache for Redisとどう違う? ● データの高耐久性 ○ 永続化目的で使える ● パフォーマンス ○ 書き込みが遅いという噂 ● セキュリティー ○ TLS必須 ● デフォルトクラスター構成 ● デフォルトパラメーター

Slide 39

Slide 39 text

セッションストアの候補

Slide 40

Slide 40 text

Redis ● 既にアプリケーションの他の箇所で使い慣れている ● 高速 ● 機能が必要十分 ● ダブルライトやクラスターを組むなどしないと可用性が不安 ○ 逆に言うとクラスターモードやダブルライトで高可用性を実現できる

Slide 41

Slide 41 text

MongoDB ● STORES のメインのDBなのでもちろん使い慣れている ● パフォーマンスへの影響が気になる ● Redisに比べるとtoo muchか ● (定期的にパッチ等のメンテナンスが入る)

Slide 42

Slide 42 text

DynamoDB ● 一部のログを保存するなどで利用はしている ● アプリケーションからは利用していないので追加実装が多い ○ Gemを増やす ○ 使い方を学ぶ ● セッションストアなのでHTTPのオーバーヘッドが気になる ● Redisに比べるとtoo muchか ● ローカル環境の整備をしないと ○ DynamoDB Local など

Slide 43

Slide 43 text

Memcached ● 運用が楽 ● マルチコア使えるので、パフォーマンス良い ● 再起動とかも速い ● 一切利用していないので追加実装が多い ○ Gemを増やす ○ 使い方を学ぶ ● 耐久性

Slide 44

Slide 44 text

Redisが良さそう!

Slide 45

Slide 45 text

Redisのインフラ構成

Slide 46

Slide 46 text

ElastiCache for Redisで高可用性を実現するには? ● クラスターモードでの運用 ● 自動フェイルオーバーの有効化 ● Multi AZ ● シャーディング ● プライマリーで障害が起きるとフラッシュ 結構意識することは多い...

Slide 47

Slide 47 text

MemoryDBなら全部あるよ! ● デフォルトクラスターモード ● 自動フェイルオーバー ● Multi AZ ● シャーディング プライマリーの障害でもデータロストしない! 新しいサービスが使えて楽しい!

Slide 48

Slide 48 text

MemoryDB良さそう!

Slide 49

Slide 49 text

懸念点 ● パフォーマンスは? ○ 書き込みが遅いという噂 ● ElastiCacheより料金がお高め ○ クラスターモードのみなので細かなサイズ調整が難しい場合も ○ 大きめのインスタンスしか選べなかった ■ 今はt4gも! ○ 今回は許容範囲ということで富豪的解決!

Slide 50

Slide 50 text

MemoryDB for Redis の導入過程と失敗談

Slide 51

Slide 51 text

調査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/ 書き込みが遅いらしい

Slide 52

Slide 52 text

調査2 AWSの方からも... ● > 書き込みレイテンシーについては、 一桁ミリ秒 となります。これは、高い 可用性を担保するために、Multi-AZへの書き込みを反映させることによるも ので、仕組み上の制約となります。 > 一桁ミリ秒では要件が満たされない、かつElastiCache (Redis)の可用性が 許容できるならば、ElastiCache (Redis)を使っていくことが推奨されます。 > よくある可用性とレイテンシーのトレードオフですね ○ 噂通り だけどこの性能差は本当に問題になるのか? 試してみよう!

Slide 53

Slide 53 text

検証 ● 先ずは書き込みだけ有効にしてリリースしてみる ○ 元々Cookieとの両書き期間を設ける予定だったし! ○ 幸いCloudWatch MetricsやDatadogのAPMなど可視化は万全! アプリケーション 当代 Cookie 次代 MemoryDB Write Read Write

Slide 54

Slide 54 text

検証結果1 書き込みのみ ● 5%程度処理時間 を使っているもの の、平均レイテン シーに大きな変化 は無し! ● スペック上書き込 みが遅くてもセッ ションストア用途 なら問題無さそ う! リリース 5%増量

Slide 55

Slide 55 text

検証結果2 読み書き両方 ● 読み書き両方を 有効にしてもほ ぼ影響無し! リリース 変化なし!

Slide 56

Slide 56 text

移行成功!...?

Slide 57

Slide 57 text

Evictionされない! part 1 ● ある日Redisのメモリー逼迫アラートが!!! ● 急いでクラスターをスケールアウト! ● 相当余裕をもってサイジングしたんだけど... ● どうしてEvictionされないんだろう? ● maxmemory-policy: noeviction がデフォルト! ○ ElastiCacheだとvolatile-lruだった

Slide 58

Slide 58 text

Evictionされない! part 2 ● ある日Redisのメモリー逼迫アラートが!!! ● どうしてEvictionされないんだろう? ● 分からないのでAWSサポートの方に泣きつくと... ● TTL付いてないキーが一杯ありますよ! ○ 我々のアプリケーションの問題だったことが判明m(__)m

Slide 59

Slide 59 text

STORESのセッションはMemoryDBで元気に稼働中!

Slide 60

Slide 60 text

まとめ ● 高耐久で高速なインメモリーデータベースはMemoryDBはあり! ○ お手軽に高耐久なRedisクラスターが使えます! ○ 書き込みパフォーマンスについては用途次第で問題にはならない! ● AWSサポートの方々の優しさで毎日救われています!