Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DBコネクションプール Database Connection Pooling

DBコネクションプール Database Connection Pooling

Avatar for Neurogica

Neurogica

June 11, 2026

More Decks by Neurogica

Other Decks in Technology

Transcript

  1. • DBのコネクション数意識してる? • DB接続のコストを測る • コネクションプールの仕組み • LambdaとPrismaで起きていること • 解決策:RDS

    Proxy / PgBouncer • まとめ • おまけ アジェンダ はじめに コネクションプール コネクション爆発 まとめ 解決策 2 おまけ © Neurogica Inc.
  2. DB接続とは何か ̶ コストを確認する 接続確⽴だけで 50〜200ms かかることも。 クエリ⾃体が 5ms でも、接続コストが⽀配的になる。 •

    DBに「繋ぐ」とき、裏では複数のステップが⾛る TCP ハンドシェイク TLS ネゴシエーション DB認証 クエリ SYN → SYN-ACK → ACK(往復レイテンシ × 1.5) 証明書検証 + 鍵交換(数往復) ユーザー名/パスワード検証、セッション確⽴ SELECT * FROM users 4 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  3. プールなしだと何が起きるか 毎回フルコスト レスポンスが遅延 • リクエストごとに接続 req #1 接続 → クエリ

    → 切断 req #2 接続 → クエリ → 切断 req #3 接続 → クエリ → 切断 • 同時アクセスが増えると req × 100 DB接続 × 100 PostgreSQLのデフォルト最⼤接続数は 100 同時リクエストが増えると接続上限エラー 5 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  4. コネクションプールの仕組み • 接続を使い回すことで、確⽴コストを払うのは最初だけ conn #1 待機中 conn #2 待機中 conn

    #3 使⽤中 conn #4 使⽤中 conn #5 待機中 リクエストが来た時 1. プールから「待機中」の接続を借りる 2. クエリを実⾏ 3. 接続をプールに返却(切断しない) プールが空のとき • 新しい接続を確⽴(上限まで) • 上限に達したらキューで待機 • タイムアウトで接続エラー 6 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  5. プールあり vs なし ̶ ⽐較 • プールなし • プールあり req

    #1 接続 150ms → クエリ → 切断 req #2 接続 150ms → クエリ → 切断 req #3 接続 150ms → クエリ → 切断 req #1 借りる 1ms → クエリ → 切断 req #2 借りる 1ms → クエリ → 切断 req #3 借りる 1ms → クエリ → 切断 起動時 接続確⽴(150ms) 7 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  6. コネクション爆発 • Lambdaはリクエストに応じて並列にインスタンスが増える Lamdba × N DB接続 × N ×

    pool_size 接続上限エラー • 各Lambdaインスタンスが独⽴したプールを持つ • インスタンス数 × pool_size = 総接続数 • スケールアウトするほど接続が爆発する 9 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  7. 解決策:接続を外部で管理する • Lambdaとアプリの間に外部コネクションプーラーを置く Lamdba #1 外部プーラー RDS Proxy / PgBouncer

    DB RDS Proxy • RDS / Aurora に対応 • コスト:DB料⾦に追加で発⽣ Lamdba #2 PgBouncer(OSS) • PostgreSQL専⽤の軽量プーラー • コスト:インフラ費⽤のみ 10 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  8. RDS Proxy を使った場合 • DBとのコネクションはずっと貼っているが、DBとのやり取りはクエリ実⾏の短時間 → 集約可能 Lamdba #1 RDS

    Proxy クライアント接続: 10 DB接続: 3 DB Lamdba #2 Lamdba #3 Lamdba #4 Lamdba #5 11 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  9. まとめ • DB接続には TCP / TLS / 認証 のコストがある •

    コネクションプールは接続を 再利⽤ してコストを償却する • Lambdaでは インスタンスごとに独⽴したプール ができる → 接続爆発 • 解決策は 外部プーラー(RDS Proxy / PgBouncer) で接続を集約する • まず PrismaClientをモジュールスコープに出す だけでも効果あり • サーバインスタンス1つでいくつコネクションを貼っていて、DBの上限がいくつなのかを意 識しよう 12 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ © Neurogica Inc.
  10. Prismaのコネクション • v6だと ◦ デフォルトコネクションプール数:CPU物理コア数×2+1 ◦ プールからの接続取得タイムアウト:10秒 • v7だと ◦

    デフォルトコネクションプール数:10 ◦ プールからの接続取得タイムアウト:無制限 14 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ [1] : https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool © Neurogica Inc.
  11. Postgresのコネクション • DB接続数は多ければ速いわけではない • 接続数をリソースに従って絞った⽅が多くの場合レイテンシもスループットも良くなる • 接続ごとにプロセスが⽣成されるからコンテキストスイッチやキャッシュ、ロックによって 性能が劣化する • ベンチマークの経験則では以下が良いらしい

    ◦ 最適なアクティブ接続数 ≈ (core_count × 2) + effective_spindle_count ◦ スピンドルはHDDの軸を指し、SSDなら0 15 はじめに コネクションプール コネクション爆発 まとめ 解決策 おまけ [2] : https://wiki.postgresql.org/wiki/Number_Of_Database_Connections © Neurogica Inc.