Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | - |
- 動機GitLab.comの安定性とパフォーマンス
- 使用例
- GitLab.com上の問題のあるテーブル
- ターゲットGitLab.com上のすべての物理テーブルがインデックスを含めて100GB未満
- 解決方法
- ゴール
- 誰
データベースのスケーラビリティ:GitLab.comでは、ディスク上のテーブルサイズを100GB未満に制限します。
このドキュメントは、GitLab.comのテーブルサイズの削減と制限に向けた提案です。テーブルサイズをある閾値に制限することで、測定可能な目標を設定します。これは、データベースの焦点化と意思決定を推進するための指標として使われます。GitLab.comが成長するにつれて、私たちは違反の防止やその他の修正のためにどのテーブルに取り組む必要があるかを継続的に再評価しています。
これは厳密なルールではなく、テーブルを分割したりサイズを小さくしたりする作業が必要であることを示すものです。
これは、全体像を描くDatabase Shardingの設計図との関連で読まれることを意図しています。ここでの提案は、ストレージ要件を減らし、データモデリングを改善することを目的とした、以下の「デブロートステップ」の一部と考えられます。パーティショニングは標準的なツールベルトの一部です。可能であれば、物理的なテーブルサイズを大幅に削減するソリューションとして、すでにパーティショニングを使用することができます。パーティショニングは標準的なツールベルトの一部であり、可能であれば、物理的なテーブルサイズを大幅に削減するためのソリューションとしてパーティショニングを使用することができます。
動機GitLab.comの安定性とパフォーマンス
GitLab.comの大きなテーブルは、オペレーションにとっても開発者にとっても大きな問題です。それらは様々な問題を引き起こします:
- クエリの時間、ひいてはアプリケーション全体のパフォーマンスの低下
- テーブルのメンテナンスにコストがかかるGitLab.comではバキューム・アクティビティが重要な問題となっています。大規模なテーブルでは1日に1回という頻度の低い処理しか行われず、バキュームの実行には何時間もかかります。これは様々な悪影響を及ぼし、非常に大きなテーブルはデータベースの一見無関係に見える部分にも影響を与える可能性があります。
- 大規模なテーブルのデータマイグレーションは、実装が非常に複雑で、開発者のオーバーヘッドになります。GitLab.comの安定性の問題を引き起こす可能性があり、大きなデータセットで実行するのに長い時間がかかります。
- インデックスのサイズは重要です。インデックスの小さな部分がメモリに保持されるため、パフォーマンスに直接影響します。また、インデックスのメンテナーも難しくなります(リパッキングを考えてみてください)。
- インデックスの作成時間が大幅に増加します。2021年では、1つのB-Treeインデックスに対して、B-Treeの作成に最大6時間かかっています。これは頻繁にデプロイする能力に影響を与え、バキューム関連の問題(クリーンアップの遅延)につながります。
- 私たちは緩和するために多くのインデックスを追加しがちですが、これは最終的に大きなオーバーヘッドを引き起こし、クエリプランナを混乱させる可能性があります。
使用例
最も顕著な例として、ci_builds
テーブルの2021年6月現在のサイズは1.5TBで、31個のインデックスが関連付けられ、その合計サイズは1TBです。このテーブルの全体のディスク上のサイズは2.5 TBです。現在、毎月300GBずつ増加しています。対策を講じなければ、年末には5TB近くになると思われます。
以下の例は、非常に大きなテーブルがGitLab.comのインシデントの根本原因であることが多いことを示しています。
- バキューム・アクティビティが頻繁に行われず、長い間実行されているため、CIキューイングのクエリ・パフォーマンスが何度も低下しています。
-
ci_builds
のような大規模なテーブルでは、インデックス作成にかかる時間は、混雑時には1.5時間から6時間の間で変動します。このプロセスは、マイグレーションが同期的に実行されるため、デプロイをブロックし、頻繁にデプロイする能力を低下させます。 - 大規模なインデックスの作成は、データベースのプライマリでのアクティビティを急増させます:
-
merge_request_diff_commits
テーブルでネットワークが高飽和状態になりました、 - 週末に定期的なインデックス再作成アクティビティが発生すると、WALキューが増大します(復旧目標に影響)、
-
notes
テーブル:メンテナンスのためにGINトリグラムインデックスを再作成することはほとんど不可能になり、他のバキュームオペレーションをブロックするため、最初の試行では12時間後に中止しなければなりませんでした。
-
GitLab.com上の問題のあるテーブル
これは、2021年6月中旬現在、GitLab.comにあるテーブルの総サイズ(インデックスサイズも含む)別にTOP30を表示したものです。table_size, index_size
は、実際のデータと関連するインデックスそれぞれのディスク上のサイズです。percentage_of_total_database_size
は、データベースサイズに対するテーブル総サイズの比率を表示しています。
見てわかるように、現在 1 TB を超える非常に大きなテーブルが存在し、それらは非常に大きなインデックスを持つ傾向があります。
もう1つの観察は、多数のインデックスを持つテーブルもあり、インデックス・サイズの合計が格納されているデータよりもかなり大きくなる可能性があるということです。例えば、deployments
は30GBのサイズであり、さらに24のインデックスにまたがって123GBのインデックスデータがあります。
テーブル | 合計サイズ | テーブルサイズ | インデックスサイズ | インデックス数 | データベース全体のサイズに対する割合 |
---|---|---|---|---|---|
ci_builds | 2975 GB | 1551 GB | 941 GB | 30 | 22.7 |
merge_request_diff_commits | 1890 GB | 1454 GB | 414 GB | 2 | 14.4 |
ci_build_trace_sections | 1123 GB | 542 GB | 581 GB | 3 | 8.6 |
notes | 748 GB | 390 GB | 332 GB | 13 | 5.7 |
merge_request_diff_files | 575 GB | 481 GB | 88 GB | 1 | 4.4 |
events | 441 GB | 95 GB | 346 GB | 12 | 3.4 |
ci_job_artifacts | 397 GB | 187 GB | 210 GB | 10 | 3.0 |
ci_pipelines | 266 GB | 66 GB | 200 GB | 23 | 2.0 |
taggings | 238 GB | 60 GB | 179 GB | 5 | 1.8 |
ci_builds_metadata | 237 GB | 88 GB | 149 GB | 5 | 1.8 |
issues | 219 GB | 47 GB | 150 GB | 28 | 1.7 |
web_hook_logs_202103 | 186 GB | 122 GB | 8416 MB | 3 | 1.4 |
ci_stages | 182 GB | 58 GB | 124 GB | 6 | 1.4 |
web_hook_logs_202105 | 180 GB | 115 GB | 7868 MB | 3 | 1.4 |
merge_requests | 176 GB | 44 GB | 125 GB | 36 | 1.3 |
web_hook_logs_202104 | 176 GB | 115 GB | 7472 MB | 3 | 1.3 |
web_hook_logs_202101 | 169 GB | 112 GB | 7231 MB | 3 | 1.3 |
web_hook_logs_202102 | 167 GB | 111 GB | 7106 MB | 3 | 1.3 |
sent_notifications | 166 GB | 88 GB | 79 GB | 3 | 1.3 |
web_hook_logs_202011 | 163 GB | 113 GB | 7125 MB | 3 | 1.2 |
push_event_payloads | 162 GB | 114 GB | 48 GB | 1 | 1.2 |
web_hook_logs_202012 | 159 GB | 106 GB | 6771 MB | 3 | 1.2 |
web_hook_logs_202106 | 156 GB | 101 GB | 6752 MB | 3 | 1.2 |
deployments | 155 GB | 30 GB | 125 GB | 24 | 1.2 |
web_hook_logs_202010 | 136 GB | 98 GB | 6116 MB | 3 | 1.0 |
web_hook_logs_202009 | 114 GB | 82 GB | 5168 MB | 3 | 0.9 |
security_findings | 109 GB | 21 GB | 88 GB | 8 | 0.8 |
web_hook_logs_202008 | 92 GB | 66 GB | 3983 MB | 3 | 0.7 |
resource_label_events | 66 GB | 47 GB | 19 GB | 6 | 0.5 |
merge_request_diffs | 63 GB | 39 GB | 22 GB | 5 | 0.5 |
ターゲットGitLab.com上のすべての物理テーブルがインデックスを含めて100GB未満
オペレーションの安定性を維持・向上し、開発者の負担を軽減するために、私たちはGitLab.comの物理テーブル(インデックスを含む)のテーブルサイズを100GB未満にすることを目標としています。これには多くのメリットがあります:
- クエリのパフォーマンスが向上し、クエリプランが安定します。
- バキューム実行時間を大幅に短縮し、バキューム実行の頻度を増やして健全な状態を維持することで、データベース・プライマリのオーバーヘッドを削減
- インデックスの作成時間が大幅に短縮(インデックスごとに読み込むデータが大幅に減少)
- インデックスのサイズが小さくなり、より効率的にメンテナーでき、メモリへの収まりが良くなります。
- データマイグレーションは推論しやすく、実装と実行に時間がかかりません。
この目標は現実的です:テーブルのサイズは、機能の使用状況、コードの変更、その他の要因に依存します。物理的なテーブルのサイズをきっちりと制限できるようなソリューションが常に見つかるとは限りません。しかし、それは許容範囲内であり、私たちは主にGitLab.comの状況をコントロール下に保つことを目指しています。私たちはGitLab.comの状況に合わせて取り組み、頻繁に再評価を行っています。
物理的なテーブルの最大サイズが一定になるような変更は可能ですが、必ずしもそうである必要はありません。例えば、テーブルを固定数のパーティションに分割するハッシュ・パーティショニングを考えてみましょう。時間の経過とともにデータが増加すると、個々のパーティションのサイズも大きくなり、最終的に再び閾値サイズに達する可能性があります。私たちはテーブルのサイズが一定になるように努力していますが、このような特性を持たず、かなりの時間状況を改善するような、より簡単なソリューションを出荷することも許容されます。
このように、リファクタリング後の物理テーブルの目標サイズは状況によって異なり、明確なルールはありません。過去のデータ増加を考慮し、物理テーブルが再び100GBの閾値に達する時期を予測することをお勧めします。これにより、モデルを再検討する必要が生じるまで、特定のソリューションがどのくらいの期間続くと予想されるかを理解することができます。
解決方法
テーブルサイズを小さくするための標準的なソリューションはありません!
- 保持:不要なデータを削除します。例えば、古いレコードや不要なレコードは期限切れにします。
- STIの削除: アンチパターンとされる単一テーブル継承をまだ数カ所で使用しています。これを再設計することで、データを複数のテーブルに分割することができます。
- インデックスの最適化:不要なインデックスを削除し、可能であれば重複するインデックスを統合します。
- データ型の最適化:データ型の決定をレビューし、可能であればデータ型を最適化(例:enumカラムにtextではなくintegerを使用)。
- パーティショニング:共通のアクセス・ディメンジョンがある場合は、パーティショニング・スキームを適用します。
- 正規化:関係モデリングをレビューし、正規化テクニックを適用して重複データを削除します。
- テーブルの垂直分割:カラムの使用法をレビューし、テーブルを縦に分割します。
- 外部化:大きなデータ型をデータベースから完全に移動します。例えば、JSONドキュメントは、特にフィルタリングに使用しない場合は、オブジェクトストレージなど、データベースの外部に保存した方が良いでしょう。
正規化のようなソリューションでは、これはトレードオフの関係にあります。非正規化モデルは適切に使用された場合、クエリを高速化できますが、テーブルサイズは犠牲になります。モデルを正規化したり、テーブルを分割したり、データを外部化したりする場合は、パフォーマンスへの影響を理解し、パフォーマンスに大きな影響を与えないテーブルサイズを削減するソリューションを見つけるよう努めます。
取り組み例
エピック・データベースの効率化の下に、さらに多くの例が整理されています。
- のインデックスの数を減らします。
ci_builds
- のコミッターと作成者の詳細の正規化と重複排除。
merge_request_diff_commits
- の保持戦略
ci_build_trace_sections
- 古い CI ジョブのメタデータをハード削除するワーカーの実装
-
merge_request_diff_files
< 100 GB のターゲット (エピック) に違反している場合
ゴール
~group::database
](https://gitlab.com/groups/gitlab-org/-/epics/6211) のための[エピックは、目標の確立と伝達、そして目標達成のために必要な変更の特定と提案のための意思決定を推進します。これらの変更は、主にデータ(およびそれを使用する機能)を所有する各ステージグループによって推進されるべきであり、~group::database
。
誰
GitLabデータベースチームと各ステージグループによって、問題のあるテーブルのソリューションを特定します。
ロール | 誰 |
---|---|
Author | アンドレアス・ブランドル |
エンジニアリングリーダー | クレイグ・ゴメス |