Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Google Cloud の新サービス「Memorystore for Redis Clust...
Search
gree_tech
PRO
October 25, 2024
Video
Technology
1
210
Google Cloud の新サービス「Memorystore for Redis Cluster 」導入事例:「Memorystore for Memcached」からの移行と運用
GREE Tech Conference 2024で発表された資料です。
https://techcon.gree.jp/2024/session/TrackB-6
gree_tech
PRO
October 25, 2024
Tweet
Share
Video
More Decks by gree_tech
See All by gree_tech
REALITY株式会社における開発生産性向上の取り組み: 失敗と成功から学んだこと
gree_tech
PRO
2
190
『ヘブンバーンズレッド』におけるフィールドギミックの裏側
gree_tech
PRO
2
150
セキュリティインシデント対応の体制・運用の試行錯誤 / greetechcon2024-session-a1
gree_tech
PRO
1
150
『アナザーエデン 時空を超える猫』国内海外同時運営実現への道のり ~別々で開発されたアプリを安定して同時リリースするまでの取り組み~
gree_tech
PRO
1
120
『アサルトリリィ Last Bullet』におけるクラウドストリーミング技術を用いたブラウザゲーム化の紹介
gree_tech
PRO
1
150
UnityによるPCアプリの新しい選択肢。「PC版 Google Play Games」への対応について
gree_tech
PRO
1
240
実機ビルドのエラーによる検証ブロッカーを0に!『ヘブンバーンズレッド』のスモークテスト自動化の取り組み
gree_tech
PRO
1
180
"ゲームQA業界の技術向上を目指す! 会社を超えた研究会の取り組み"
gree_tech
PRO
1
230
Jamstack でリニューアルするグリーグループのメディア
gree_tech
PRO
2
390
Other Decks in Technology
See All in Technology
レンジャーシステムズ | 会社紹介(採用ピッチ)
rssytems
0
150
【re:Invent 2024 アプデ】 Prompt Routing の紹介
champ
0
150
Oracle Cloud Infrastructure:2024年12月度サービス・アップデート
oracle4engineer
PRO
0
190
ガバメントクラウドのセキュリティ対策事例について
fujisawaryohei
0
550
Opcodeを読んでいたら何故かphp-srcを読んでいた話
murashotaro
0
260
PHPerのための計算量入門/Complexity101 for PHPer
hanhan1978
5
150
5分でわかるDuckDB
chanyou0311
10
3.2k
ゼロから創る横断SREチーム 挑戦と進化の軌跡
rvirus0817
2
270
How to be an AWS Community Builder | 君もAWS Community Builderになろう!〜2024 冬 CB募集直前対策編?!〜
coosuke
PRO
2
2.8k
終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024
yositosi
16
13k
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
300
WACATE2024冬セッション資料(ユーザビリティ)
scarletplover
0
210
Featured
See All Featured
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
127
18k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
450
GraphQLとの向き合い方2022年版
quramy
44
13k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
28
2.1k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
0
98
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Unsuck your backbone
ammeep
669
57k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
29
2k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
2
170
Transcript
Google Cloud の新サービス 「Memorystore for Redis Cluster 」導入事例 :「Memorystore for
Memcached」からの 移行と運用 株式会社 WFS エンジニア 檜垣颯汰
檜垣颯汰 グリー株式会社に2022年6月新卒入社。株式会社 WFSにてプロダクトのサーバーエンジニアとして 開発、運用、保守に幅広く従事。2024年9月より サーバーリードとしてチームを牽引している。 株式会社 WFS サーバーエンジニア 2
アジェンダ • プロダクトの課題:Memorystore for Memcached • Memorystore for Memcached 移行先の検討
• Memorystore for Redis Cluster 導入試験 • Memorystore for Redis Cluster 負荷検証 • Memorystore for Redis Cluster の本番運用について • まとめ • 今後の展望 3
プロダクトの課題: Memorystore for Memcached 4
プロダクトの前提 • Google Kubernetes Engine (GKE) + PHP + Apache
• キャッシュサーバーとして Memorystore for Memcached を使用 • 極力全体メンテナンスを行わない運用 5
プロダクトの課題 キャッシュサーバーとして Memorystore for Memcached を使用 以下の問題を抱えていた • メンテナンスで最大数時間停止する •
台数変更の運用コストが高い • フェイルオーバーできない 6
課題 1 メンテナンスで最大数時間停止する メンテナンスウィンドウは最低 3 時間必要 > ウィンドウの期間は 3〜8 時間の間でユーザーが構成できます。
https://cloud.google.com/memorystore/docs/memcached/about-maintenance#duration-faq 実際にメンテナンスを行なった際は 3 時間を少し超えて完了した 7
課題 2 台数変更の運用コストが高い ノードの増減時はクライアント側のノードリストを手動で変更する必要がある • Memorystore for Memcached はヘルスチェックが取れない ノード数を増減させると、キースペースが再分散されてしまいキャッシュミスが起
こってしまうため慎重なオペレーションが必要 8
課題 3 フェイルオーバーができない Memcached にはプライマリ・レプリカという概念が存在しない ノードが落ちた時、手動で対応しない限り同じノードにアクセスし続けてしまう • Memorystore for Memcached
はヘルスチェックが取れない 9
プロダクトの課題(再掲) キャッシュサーバーとして Memorystore for Memcached を使用 以下の問題を抱えていた • メンテナンスで最大数時間停止する •
台数変更の運用コストが高い • フェイルオーバーできない 10
プロダクトの課題(再掲) キャッシュサーバーとして Memorystore for Memcached を使用 以下の問題を抱えていた • メンテナンスで最大数時間停止する •
台数変更の運用コストが高い • フェイルオーバーできない 11 Memorystore for Memcached からの移行を検討
Memorystore for Memcached 移行先の検討 12
移行先候補 (1) Memorystore for Redis • ◦ すでにランキングなどで使用しているので移行が楽 • ×
プライマリのスケールアウトができず、CPUが頭打ちになる懸念あり 13
移行先候補 (2) 自前でキャッシュサーバーを立てる • ◦ 細かい制御ができる • × メンテナンスコストが高い 14
移行先候補 (3) Memorystore for Redis Cluster • ◦ 水平スケール・フェイルオーバー の運用コストが少ない
• △ リリースしたばかりのため、他社事例が 0 15
• 水平スケール・フェイルオーバー によりサービスの可用性を向上できる • 運用コストを最小限に抑えられる 上記をともに満たす Memorystore for Redis Cluster
を検討 移行先の検討 16 クライアント (PHPサーバー) プライマリ レプリカ
Memorystore for Redis Cluster 導入試験 17
導入試験 Memorystore for Redis Cluster によって 既存の課題が解決するかどうかを 実際の運用にそって検証 18
プロダクトの課題(再掲) 1. メンテナンスで最大数時間停止する 2. 台数変更の運用コストが高い 3. フェイルオーバーできない 19
課題 1: メンテナンスで最大数時間停止する メンテナンスはダウンタイムなしと記載あり https://cloud.google.com/memorystore/docs/cluster/about-maintenance#scheduled_maintenance • メンテナンスをテストすることはできない 20
課題 2: 台数変更の運用コストが高い 公式ドキュメントによると、無停止でスケーリングできる 21 https://cloud.google.com/memorystore/docs/cluster/about-scaling-instance-capacity
課題 2: 台数変更の運用コストが高い また、Web UI 上で簡単に台数変更ができる クライアント側で台数の変更を意識しなくて良い 22
課題 2: 台数変更の運用コストが高い 負荷をかけずに • 3台 → 5台(増台) • 5台
→ 3台(減台) は5分以内で完了した 23
課題 2: 台数変更の運用コストが高い 負荷をある程度(10000 コネクション、15000 コマンド/s 程度) かけて増台・減台 5 分以内に完了し、15
分程度でコネクションが分散された Redis コマンドは接続エラーなどで0 ~ 数件失敗 24
課題 2: 台数変更の運用コストが高い 負荷の高い状況(32000 コネクション、50000 コマンド/s 程度) だと 2 時間経過のち、失敗
→本番では使用しないタイミングで 台数変更を行う運用に 25
課題 3: フェイルオーバーできない 公式では数十秒〜数分と記載あり https://cloud.google.com/memorystore/docs/cluster/ha-and-replicas#failover_and_node_rep air_duration • フェイルオーバーをテストすることはできない 26
導入試験結論 1. メンテナンスで最大数時間停止する 2. 台数変更の運用コストが高い 3. フェイルオーバーできない 27
導入試験結論 1. △ メンテナンスで最大数時間停止する 2. ◦ 台数変更の運用コストが高い 3. △ フェイルオーバーできない
一部導入後でないと実際に確認できないものはありつつも、 課題の解決が望める 28
ロールバックの準備 前述の結論の通り、移行が確実に成功するとは言い切れない 本番リリース時に問題が発生した場合に備え、ロールバックできるようにした 29
ロールバックの準備 具体的には • 一時的にキャッシュサーバーが使用不可になっても問題ないように処理を 改善 • その上で、キャッシュサーバーの使用可否をプロダクト独自の管理ツール から設定できるように実装し、ロールバックなど切り替えの場面で使用で きるようにした 30
Memorystore for Redis Cluster Memorystore for Memcached ロールバックの流れ 31 クライアント
(PHPサーバー) Memorystore for Redis Cluster にアクセスしている状態
DB ロールバックの流れ 32 社内管理ツール 管理ツールから使用可否を設定 canUse = false Memorystore for
Redis Cluster Memorystore for Memcached クライアント (PHPサーバー) クライアント (PHPサーバー)
DB ロールバックの流れ 33 社内管理ツール キャッシュ使用時にDBから使用可否を判断 canUse = false Memorystore for
Redis Cluster Memorystore for Memcached クライアント (PHPサーバー) クライアント (PHPサーバー) APCu
DB ロールバックの流れ 34 社内管理ツール canUse = false ならアクセスを止める canUse =
false Memorystore for Redis Cluster Memorystore for Memcached クライアント (PHPサーバー) ❌ クライアント (PHPサーバー) APCu
DB ロールバックの流れ 35 社内管理ツール 設定をデプロイし、止めたまま向き先を変える canUse = false Memorystore for
Redis Cluster Memorystore for Memcached クライアント (PHPサーバー) ❌ クライアント (PHPサーバー) APCu
DB ロールバックの流れ 36 社内管理ツール canUse = true にし、切り替え完了 canUse =
true Memorystore for Redis Cluster Memorystore for Memcached クライアント (PHPサーバー) クライアント (PHPサーバー) APCu
Memorystore for Redis Cluster 負荷検証 37
Memorystore for Redis Cluster 負荷検証 導入試験で課題の解決が見込めた プロダクトのユースケースを満たせるか負荷試験で検証 38
負荷試験の目標 • API サーバー が 5000 RPS 以上捌けること • Memorystore
for Redis Cluster が 50000 コマンド/s 以上捌けること • その他メトリクスに問題が生じないこと ◦ CPU 使用率 ◦ メモリ使用量 ◦ コネクション数 など • プロダクトの挙動に問題が生じないこと 39
負荷試験の目標:その他 プロダクトの挙動に問題が生じないこと • 負荷試験でのロジックやデータ不整合などのエラーが 0 件 • API サーバーのレイテンシが許容される範囲内であること 40
負荷試験での設定 Redis ライブラリとして phpredis を使用 41
API サーバー • GKE API pod: 1000台 • Apache MaxRequestWorkers:
25 Redis Cluster • persistent connection: true • シャード: 3台(必要あれば増台) • レプリカ: シャードごとに 1台 その他負荷試験の設定 42 クライアント (PHPサーバー) プライマリ レプリカ
persistent connection 永続的接続 PHPの worker プロセスが終了するまでコネクションを継続する persistent connection = false
だと 毎回 PHP と Redis Cluster でコネクションを貼るため、I/O 帯域を圧迫しや すい 43
PHP API サーバー(Pod) コネクションのイメージ 44 Apache worker Apache worker Apache
worker PHP API サーバー(Pod) … … プライマリ/レプリカ
45 コネクション起因のエラー persistent connection = false
46 persistent connection = false 新規コネクション 1000/s 程度
47 エラーは 0 persistent connection = true
48 persistent connection = true ピークで 500/s の時もあるが、一瞬 なので影響なし
Redis Cluster 負荷試験 結果 49
50 5000 RPS~を捌いている 一部 worker が落ちた
51 おおよそ 30000 弱 を推移
52 特に reject は無し
53 CPUに余裕はある
54 70000 コマンド/s 程度
負荷試験の目標:その他 プロダクトの挙動に問題が生じないこと • 負荷試験でのエラーが 0 件 • API サーバーのレイテンシが許容の範囲内 以上より、問題ないと判断
55
負荷試験の目標(再掲) • API Server が 5000 RPS 以上捌けること • Memorystore
for Redis Cluster が 50000 コマンド/s 以上捌けること • その他メトリクスに問題が生じないこと ◦ CPU 使用率 ◦ メモリ使用量 ◦ コネクション数 • プロダクトの挙動に問題が生じないこと 56
負荷試験の目標(再掲) • ◦ API Server が 5000 RPS 以上捌けること •
◦ Memorystore for Redis Cluster が 50000 コマンド/s 以上捌けること • △ その他メトリクスに問題が生じないこと ◦ ◦ CPU 使用率 ◦ ◦ メモリ使用量 ◦ △ コネクション数 • ◦ プロダクトの挙動に問題が生じないこと 57
コネクション数の問題 persistent connection によって、コネクション数が上限を超える • 2024年 3月時点では、10000 がコネクション上限だった 58
コネクション数の問題 persistent connection によって、コネクション数が上限を超える • 2024年 3月時点では、10000 がコネクション上限だった • 本番想定として、
500 pod ✖ 25 worker + α ~ 最大 15000 コネクショ ン程度は見込まれたため、削減する必要があった 59
コネクションのイメージ(再掲) コネクション数 🟰 Pod 台数 ✖ Pod 1台あたりのworker数 でおおよそ見積もることができる 60
PHP API サーバー(Pod) Apache worker Apache worker Apache worker PHP API サーバー(Pod) … … プライマリ/レプリカ
コネクション数の問題:対策案 • HPA(Horizontal Pod Autoscaler)のCPU utilization target を上げる • persistent
connection = false にする • Pod 1台あたりの Apache Worker 数を減らす 61
コネクション数の問題:対策案 1 HPAのCPU utilization target を上げる コネクション数 = Pod 台数
× Pod 1台あたりのworker数 Pod 台数 を減らせば良い 62
コネクション数の問題:対策案 1 HPAのCPU utilization target を上げる 具体例:4000 RPS, podあたりworker数が 25
の場合 63 CPU target Pod 1台のRPS Pod 台数 コネクション数 before 25 % 5 800 20000 after 50 % 10 400 10000
コネクション数の問題:対策案 1 HPAのCPU utilization target を上げる CPU target を上げると その分動作が不安定になる可能性があるため
様子を見ながら上げるしかない 64
コネクション数の問題:対策案 2 persistent connection をやめる 都度繋ぎ直しになるので、コネクション数は劇的に減る ただ、前述の通りネットワーク帯域を圧迫するため、推奨できない 65
コネクション数の問題:対策案 3 Pod 1台あたりの Apache Worker 数を減らす コネクション数 = Pod
台数 × Pod 1台あたりの worker 数 Pod 1台あたりの worker 数を減らせば良い 66
コネクション数の問題:対策案(再掲) • HPA の CPU utilization target を上げる • persistent
connection をやめる • Pod 1台あたりの Apache Worker 数を減らす 67
コネクション数の問題:対策案(再掲) • △ HPA の CPU utilization target を上げる •
△ persistent connection をやめる • ◦ Pod 1台あたりの Apache Worker 数を減らす 68
コネクション数の問題:対策案(再掲) • △ HPA の CPU utilization target を上げる •
△ persistent connection をやめる • ◦ Pod 1台あたりの Apache Worker 数を減らす 69 ここに朗報が 飛び込む
MaxClients の上限解放 2024年 4月 Max Clients(コネクションの最大値) 10000 → 最大 64000
まで引き上げられた 負荷試験では 30000 コネクション で目標値に到達していたため、十分と判断した 70 https://cloud.google.com/memorystore/docs/cluster/quotas
負荷試験の目標(再掲) • ◦ API Server が 5000 RPS 以上捌けること •
◦ その他メトリクスに問題が生じないこと ◦ ◦ CPU 使用率 ◦ ◦ メモリ使用量 ◦ ◦ コネクション数 • ◦ プロダクトの挙動に問題が生じないこと 71
負荷試験の目標(再掲) • ◦ API Server が 5000 RPS 以上捌けること •
◦ その他メトリクスに問題が生じないこと ◦ ◦ CPU 使用率 ◦ ◦ メモリ使用量 ◦ ◦ コネクション数 • ◦ プロダクトの挙動に問題が生じないこと 72 負荷試験の目標を 達成できた!
Memorystore for Redis Cluster の本番運用について 73
リリース時 redis-highmem-medium 3 シャード シャードごとに 1 レプリカ カナリアリリースで少しずつリリースした 74 クライアント
(PHPサーバー) プライマリ レプリカ
75 各項目特に問題なし
76 メモリ使用率が異常に高い
メモリ使用量の増加 負荷試験では予期できなかった phpredis がデフォルトで圧縮が効いていなかったことが一番の原因 • memcached ライブラリではデフォルトで2KB以上のデータは圧縮されている https://www.php.net/manual/ja/memcached.configuration.php#ini.memcached.compression-threshold 77
メモリ使用量の増加への対処 1. シャード数の引き上げ (3台 → 6台) 2. 大きすぎるキャッシュデータを削減 3. キャッシュデータ保存時に圧縮処理を入れる
78
メモリ使用量の増加への対処 大きすぎるキャッシュデータの削減 redis-cli -h <port> --memkeys -i 1 redis-cli の機能を用いて調査
※ -i オプションで一定間隔で sleep が走るため、付けることを推奨 79
メモリ使用量の増加への対処 大きすぎるキャッシュデータの削減 以下のように結果が表示される [03.22%] Biggest string found so far 'user_cache'
with 10000 bytes 上記の調査結果を元に、削減 80
メモリ使用量の増加への対処 キャッシュデータ保存時に圧縮処理を入れる 1KB 以上のキャッシュアイテムを gzencode で圧縮 81 if (len($setValue) >
$this->config->threshold()) { $setValue = $this->gzencode($setValue, $level); } $result = $this->redisCluster->set($key, $setValue, $expiration);
メモリ使用量の増加への対処 結果として、3 シャードでも耐えられる程度まで削減できた 82
まとめ 83
まとめ 新サービス Memorystore for Redis Cluster のリリースに成功した 導入試験・負荷試験・ロールバック検証によって安心してリリースできた メモリ使用量などの問題がありつつも、台数変更などのオペレーションが楽に 行えるため、迅速に対応できた
総合的に可用性や保守性が増し、運用コストが削減できた 84
今後の展望 85
今後の展望: 短期的展望 リトライ機構の導入 Redis Cluster ノードのポートが変わった際、persistent connection で古い ノードにアクセスし続けてしまうという問題がある ➡
リトライ時にコネクションをつなぎ直すことで回避する 86
今後の展望: 中期的展望 台数増減の自動化 現状 シャード数を変更する際に、 無停止だと数秒 〜 数分 接続エラーが出てしまう リトライの導入などでエラーがほぼ出ないようになれば、可能性はある
プロダクトでは最小台数の 3台 で運用できているため、 現状は必要としていない 87
今後の展望: 長期的展望 Valkey の動向を注視 Redis の fork 先である Valkey の
マネージドサービス Memorystore for Valkey が 2024 年 8 月末 プレビューでリリースされた Redis/Redis Cluster はライセンスなどの懸念があるため、Valkey の動向も注 視していく https://redis.io/blog/redis-adopts-dual-source-available-licensing/ 88
89
ご清聴ありがとうございました 90
None