データベースの負荷分散
データベースのロードバランシングを使用すると、読み取り専用のクエリを複数のPostgreSQLノードにディストリビューションして性能を向上させることができます。
このドキュメントでは、GitLab RailsとSidekiqでデータベース負荷分散がどのように実装されているか、技術的な概要を説明します。
命名法
- ホスト:各データベースホスト。プライマリまたはレプリカ。
- プライマリ: 書き込み専用および読み書きオペレーションに使用されるプライマリのPostgreSQLホスト。
- レプリカ:セカンダリのPostgreSQLホストで、読み込みのみのオペレーションに使用されます。
- Workload:データベース接続を必要とするRailsリクエストまたはSidekiqジョブ。
コンポーネント
ロードバランシングプロセスにはいくつかのRubyクラスが関わっています。これらはすべて名前空間Gitlab::Database::LoadBalancing
にあります:
Host
LoadBalancer
ConnectionProxy
Session
Gitlab::Database::LoadBalancing::Session
Session
は、実行されたデータベースオペレーションを追跡します。そして、ワークロードがプライマリホストとレプリカホストのどちらへの接続を必要とするかを決定します。
ワークロードがActiveRecord
を介したデータベース接続を必要とする場合、ConnectionProxy
はまず、接続要求をLoadBalancer
にリダイレクトします。ConnectionProxy
は、いくつかの条件に応じて、LoadBalancer
にread
またはread_write
のいずれかの接続を要求します:
- クエリが読み取り専用か、書き込みが必要か。
-
Session
が以前に書き込みオペレーションを記録しているかどうか。 - プライマリやレプリカを優先するために、以下のような特別なブロックが使われているかどうか:
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
れます。これらの要件のしきい値は設定可能です。