はじめに
本記事は「QualiArts Advent Callender 2023」の23日目の記事になります。
23新卒のバックエンドエンジニアの苅谷です。
大学・大学院では機械学習を専攻し、入社後、モバイルゲームのバックエンドエンジニアとして働いています。
今回は、先日Google CloudからGAされたMemorystore for Redis Clusterを導入するために行なったことについて紹介していきたいと思います。
Redis Clusterとは
ここでRedis Clusterについて簡単に説明する。
詳しく学びたい方は、こちらの公式から提供された動画でわかりやすくまとめられているので、学びやすいです。
Redis Clusterとは、最低6台(ノード)のRedis Instanceから構築することができる。
3台のマスターノードと3台のリードレプリカから構成され、1つのマスターノードと1つのリードレプリカで1シャードとなる。
Redis Clusterの主な特徴としては次の2点が挙げられます。
- キーの自動分散
- キーごとに決定論的なハッシュ関数を使用して、どのシャードにキーを配置するのかを自動で決定されます。
- 自動フェイルオーバー
- どれかのマスターノードで障害が発生し、アクセスできない状態になった時に、そのノードのリードレプリカが自動でマスターノードに昇格します。
- 各ノードは他のノードと常に通信しており、どのノードで障害が発生しているのかを常に把握し自動でフェイルオーバー後の通信が勝手決まるので、つなげているアプリケーションで再接続などを行う必要がありません。
上記の二つの特徴があるため、お手軽に負荷分散と高可用性を実現できます。
しかし、シャードをスケールさせようとする時は、少し手間がかかります。
- キーの再配置
- シャードを増やすと、キーをどのシャードに配置させるかを計算するハッシュ関数が、新たなシャードも配慮に入れて計算するため、同じキーでも、スケールする前と後では違うシャードに配置される可能性が高いです。そのため、スケーリングした時に、すでに配置されたキーを新たに配置しなおす必要があります。
- Clusterの再起動
- シャードを減らす時に、一つのシャードにあるマスターノードとリードレプリカをそのままシャットダウンすると、Redis Clusterにアクセスした時に、
CLUSTER DOWN
と受信されてしまいます(たとえ取得しようしたキーが削除されたシャードに配置されていなくても)。
- シャードを減らす時に、一つのシャードにあるマスターノードとリードレプリカをそのままシャットダウンすると、Redis Clusterにアクセスした時に、
Memorystore for Redis Clusterの強み
Mmeorystoreが提供しているRedis Clusterの一番大きな特徴は、シャードのスケーリングをフルマネージメントかつダウンタイムなしで行うことができるところにあると思います。
上記のネイティブなRedis Clusterで抱えた問題点記の一つ目である「キーの再配置」を全自動で行われます。二つ目である「Redis Clusterの再起動」はDiscovery Endpointにアプリケーションで使っているRedisクライアントライブラリーを接続させると、シャードがスケールした時に、新しいシャード数をクライアントに伝えるために、再起動・再接続をする必要がないです。
Redis Clusterに移行するための労力
まずGoogle ConsoleまたはコマンドラインツールでRedis Clusterを作成します。
オプションが少ないため、それなりに簡単に作れます。
gcloud redis clusters create
--replica-count=1
--region=us-central1
--project=...
--network=...
--shard-count=10
RedisClusterを作成した後に、Discovery Endpointが発行されるので、それをアプリケーションのRedisクライアントライブラリーに繋げる。
c := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{DISCOVERY_ENDPOINT},
})
Redis Clusterに移行するための注意点
SLA
Memorystore for Redis Clusterは非常に高価なサービスで、できるだけ小さい構成で構築する需要があります。
リードレプリカなしで、3シャードが最小の構成となりますが、これだけでもそれなりに負荷分散・フルマネージドスケーリングの恩恵を受けることができます。
しかし、リードレプリカなし構成は、SLAが保証されていないため、実際のサービスで導入するときは必ずリードレプリカを1以上にすることが推奨されています。
ReadWriteモード・ReadOnlyモード
ClusterモードでRedisを構築した時に、マスターノードにある情報をリードレプリカにコピーが行われますが、一定のレプリ遅延が発生する。つまり、リードレプリカからデータを読み出すときに、データが最新では可能性があります。
Redisクライアントでは通常、ReadとWriteを両方マスターノードに対して行われます(ReadWriteモード)。リードの負荷分散を行うために、リードレプリカからデータを読み出す(ReadOnlyモード)場合は次のようにクライアントを設定する必要がある。
r := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{DISCOVERY_ENDPOINT},
ReadOnly: true,
RouteRandomly: true,
})
ReadOnlyモードを使って負荷分散する時は、必ずレプリ遅延を許容できるかどうかを考えて移行する必要がある。
おわりに
今回はネイティブのRedisClusterと、GCloudが提供しているMemorystore for Redis Clusterを違いを解説し、プロダクトに導入する場合の注意点などについて触れました。お力になれると嬉しいです!