(ニア)リアルタイムなログ基盤をFluentdからPub/Sub × Memorystore for Valkeyに移行した話
株式会社Macbee Planet で3D ADという広告配信プラットフォーム(DSP)を開発・運用しているrami(@rami)です。
3D ADでは、QPS※を最大化するために、クラウド基盤のリアーキテクチャを推進しています。
今回は、一部の(ニア)リアルタイムなログ基盤を、Fluentdを利用してMemorystore for Redisにログを書き込む構成から、Pub/SubのSubscriberからMemorystore for Valkeyにログを書き込む構成にリアーキテクチャしました。
※QPS(Queries Per Second:クエリ毎秒)とは、1秒間に処理する入札リクエストの数のこと
元の3D ADのログ基盤の構成(一部)
今回移行したログの用途
3D ADでは、入札基盤の配信制御にあたって、以下それぞれの用途でログを書き込んでいました。
- 書き込まれたログを配信ロジックから直接利用する用途
- ETL/ELT処理で加工されたデータを配信ロジック・ML・分析等に利用する用途
前者の(ニア)リアルタイムなログをFluentdからMemorystore for Redisに書き込む構成から、Pub/Sub × Memorystore for Valkeyに書き込む構成に移行しました。
今回移行したログの性質
今回移行したログの性質は、重要度が高くない、かつ、データ量が多いログになります。
3D ADとしては、ある程度の損失が許容出来るログとも言えます。
さらに、ログを書き込んでから、配信制御ですぐに利用したい(ニア)リアルタイムなログだったりもします。
表にまとめると以下です。
| ログ重要度(高) | ログ重要度(低) | |
|---|---|---|
| データ量(大) | あまり損失させたくないログ | ある程度の損失が許容出来るログ |
| データ量(小) | あまり損失させたくないログ |
元ログ基盤の構成の補足
上記でまとめた全てのログについて、一つのログ基盤で処理をしていました。
以下のような構成となっていましたが、今回の変更対象の(ニア)リアルタイムなログは赤の矢印の経路になります。
元ログ基盤の構成の課題
元の構成には以下の課題がありました。
- ログ重要度の高低、データ量の大小関係なく、StatefulSetによる固定台数のPodに全てのロギングを任せていたことから、スケーラビリティおよびクラウドコストに課題が出てきた
- Memorystore for Redisへの書き込みが失敗し続けた場合に、Podにログのバッファが溜まり続けてしまうことによって、Node Poolをパンクさせてしまって、他の重要度が高いログまで損失させる障害を引き起こしてしまう懸念があった
- 元の構成を構築・運用されていた方が社内に残っていないため、障害対応時の解決が困難になってしまっていた
Pub/Sub × Memorystore for Valkeyの構成
移行して得られたメリット
結論、元の構成にあった課題は、解決している状態にはなりました。
- フルマネージドなPub/Subに加え、ValkeyのCluster Mode、 GKEのPublisher, Subscriberと、各Deploymentがあり、元の構成よりは疎結合になっていて、各リソースをスケールをさせやすくなった
- GKEのSubscriberからMemorystore for Valkeyにログを書き込む構成になったことで、StatefulSetのPodに全く影響がないことから、重要度が高いログを損失させるリスクを落とすことが出来た
- 開発した本人やレビュワー等、構成に詳しい人が社内にいる状態になった
Memorystore for Valkeyについて
Memorystore for RedisからMemorystore for Valkeyに移行した理由
今回移行したログの性質は、QPSを増やした場合に、データ量がさらにスケールすることが見込まれていました。
そのため、Shardを水平にスケール[1]させつつ、将来的にはAutoscaler[2]を利用して、スケールイン/アウトを自動化させられないだろうかと考えたため、Memorystore for ValkeyでCluster Modeにて構築しています。
上記に加えて、以下の理由もあります。
- 本リアーキテクチャをした時点ではAutoscalerが必要な訳でもなかったため
- 私が3D ADにジョインする前から、Memorystore for Valkeyの検証が進んでいたため
- AutoscalerのValkey対応のPR[3]がmergedになっているため
- Memorystore for ValkeyはMemorystore for Redis ClusterのすべてのGA機能を備えてリリースされるとGoogle Cloudのblogに記載されていた[4]ため
Memorystore for Valkey は Memorystore for Redis Cluster のすべての GA 機能を備えてリリースされるため、お客様はほとんど同じように Valkey クラスタを使用できます(コードにも互換性があります)。
引用:https://cloud.google.com/blog/ja/products/databases/announcing-memorystore-for-valkey
Cluster Modeの注意点
ドキュメントを読まれている方には釈迦に説法かも知れませんが、Memorystore for ValkeyでCluster Modeを利用している場合、ClientはCluster Modeで設定する必要があります。
例えば、以下のような設定[5]になります。
clusterClient = redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"CLUSTER_DISC_EP_ADDR:CLUSTER_DISC_EP_PORT"},
// PoolSize applies per cluster node and not for the whole cluster.
PoolSize: 10,
ConnMaxIdleTime: 60 * time.Second,
MinIdleConns: 1,
})
ctx := context.Background()
err := clusterClient.Set(ctx, "key", "value", 0).Err()
go-redisは、Memorystore for Valkeyとも互換性[6]があるようです。
Memorystore for ValkeyのPSCの注意点
Memorystore for Valkeyで、Private Service Connectを利用して、通信する時に追加料金が発生する状況があります。
具体的には、異なるゾーン間のトラフィック[7]では、コンシューマデータ処理の料金[8]が適用されるとのことです。
処理されるデータ量に応じて課金されてしまうため、大量のデータを取り扱う場合には注意が必要です。(一敗)
同一ゾーンで通信する方が、少なくともクラウドコストは節約出来そうです。
ネットワークの料金

引用:https://cloud.google.com/memorystore/valkey/pricing?hl=ja#section-4
コンシューマデータ処理の料金

引用:https://cloud.google.com/vpc/pricing?hl=ja#psc-consumer-data-processing
まとめ
以上、一部の(ニア)リアルタイムなログ基盤をFluentdからPub/Sub × Memorystore for Valkeyに移行した背景、構成の話でした。
今後、Pub/SubやMemorystore for Valkeyを利用される方にとって、少しでも参考になれば幸いです。
Discussion