🏠 ホーム
プログラミング
インフラ
フリーランスCTO
DB
完全無料ツールまとめ
マーケティング
教育

Go × MongoDB 高トラフィック設計の落とし穴とベストプラクティス

  DB >  

MongoDBとGoを使ってアプリを開発する際、最初は 1つのDBに複数のコレクションを置くシンプルな構成で始めるケースが多いです。
ただし、将来的にスケールアウトを見据えて「コレクションごとに別のDBへ分離」する設計を検討する人もいるでしょう。

この記事では、その設計方針の注意点と、高トラフィック環境で気をつけるべき 接続・トランザクション・不整合リスク について整理します。


1. リクエストごとの Connect/Disconnect はNG

まず最初の実装例では、HTTPリクエストを受けるたびに以下のようにDBへ接続していました。

c, err := mongo.Connect(ctx, options.Client().ApplyURI(common.Mongo1))
defer c.Disconnect(ctx)

一見正しそうですが、これは リクエストごとに新しい接続プールを作って壊す ため、非常に非効率です。

正解は「アプリ起動時に一度だけコネクションプールを作り、全リクエストで共有する」ことです。

var client *mongo.Client

func InitMongo() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    client, _ = mongo.Connect(ctx, options.Client().ApplyURI(common.Mongo1))
}

func GetDB(name string) *mongo.Database {
    return client.Database(name)
}

これなら、接続のオーバーヘッドはほぼゼロに抑えられます。


2. コレクションごとにDBを分けるとどうなる?

DBを「ユーザ」「セッション」などで分割すると、以下のような特徴があります。

メリット

デメリット(オーバーヘッド)

性能面では「DBが増えること自体のコスト」は小さいですが、
アプリ側での結合や整合性管理がオーバーヘッドになるのが本質的な問題です。


3. トランザクションが使えないとどう不整合が起きるか?

MongoDBのマルチドキュメントトランザクションは 同じDB内のみでしか使えません。
DBを分けると、次のような不整合が現実的に発生します。


4. 実運用での「予期せぬエラー」例

どれも本番環境で普通に起こり得ます。


5. 対策:完全な整合性を求めない設計

もし「必ず同時にコミットされなければならない」なら、1つのDBにまとめるのが必須です。
一方で「多少ズレても後から修復できる」前提にすると、DB分割も選択肢になります。

その場合の対策は:


まとめ


💡 結論:
MongoDBを複数DBで運用するなら、
「整合性はアプリ側で工夫して担保する」
「多少のズレは後で修復する」
という思想が必要です

 

登録日:

更新日:

by

コメント         tweetでコメント