データベースの負荷分散

データベースのロードバランシングを使用すると、読み取り専用のクエリを複数のPostgreSQLノードにディストリビューションして性能を向上させることができます。

このドキュメントでは、GitLab RailsとSidekiqでデータベース負荷分散がどのように実装されているか、技術的な概要を説明します。

命名法

  1. ホスト:各データベースホスト。プライマリまたはレプリカ。
  2. プライマリ: 書き込み専用および読み書きオペレーションに使用されるプライマリのPostgreSQLホスト。
  3. レプリカ:セカンダリのPostgreSQLホストで、読み込みのみのオペレーションに使用されます。
  4. Workload:データベース接続を必要とするRailsリクエストまたはSidekiqジョブ。

コンポーネント

ロードバランシングプロセスにはいくつかのRubyクラスが関わっています。これらはすべて名前空間Gitlab::Database::LoadBalancing にあります:

  1. Host
  2. LoadBalancer
  3. ConnectionProxy
  4. Session

Gitlab::Database::LoadBalancing::Session Session は、実行されたデータベースオペレーションを追跡します。そして、ワークロードがプライマリホストとレプリカホストのどちらへの接続を必要とするかを決定します。

ワークロードがActiveRecord を介したデータベース接続を必要とする場合、ConnectionProxy はまず、接続要求をLoadBalancerにリダイレクトします。ConnectionProxy は、いくつかの条件に応じて、LoadBalancerread またはread_write のいずれかの接続を要求します:

  1. クエリが読み取り専用か、書き込みが必要か。
  2. Session が以前に書き込みオペレーションを記録しているかどうか。
  3. プライマリやレプリカを優先するために、以下のような特別なブロックが使われているかどうか:
    • use_primary
    • ignore_writes
    • use_replicas_for_read_queries
    • fallback_to_replicas_for_ambiguous_queries

LoadBalancer を指定すると、それぞれのデータベース接続プールから要求された接続が生成されます。これは

  • プライマリの接続プールからのread_write 接続。
  • レプリカの接続プールからのread 接続。

read 接続のリクエストに応答する場合、LoadBalancer はまずレプリカホスト間で接続の負荷分散を試みます。次のonline レプリカホストを online探しonline 、そのホストのコネクションプールから接続を生成 onlineします。online レプリカホストは online、レプリケーションの遅延サイズか時間のどちらかに基づいて、プライマリと最新であればonline 考慮さ onlineれます。これらの要件のしきい値は設定可能です。