Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
proposed | - |
- 相違点
- 図でのまとめ
- 変更の概要
- 最初の反復におけるデフォルトの構成についての詳細な説明
- 管理エリア設定の詳細
- 長所
- 短所
- データベースの設定例
- リクエストフロー
- 管理者
- 解決すべきその他の技術的問題
- ランナーはすべてのセルで共有されるべきですか?
- すべてのセルで競合しない一意のIDを保証するには?
このドキュメントは作業途中であり、ポッドの設計のごく初期の状態を表しています。重要な側面は文書化されていませんが、将来的には追加される予定です。これはポッドの可能性のあるアーキテクチャの1つであり、どのアプローチを実装するかを決める前に、代替案と比較検討するつもりです。このアプローチを選ばなかった理由を文書化できるように、この文書は、これを実装しないと決めた場合でも残しておきます。
提案ステートレス・ルーター
gitlab_users
,gitlab_routes
,gitlab_admin
の関連テーブルを分解して、すべてのセル間で共有できるようにし、どのセルでもユーザーを認証してリクエストを正しいセルにルーティングできるようにします。セルは自分が所有していないリソースに対するリクエストを受け取るかもしれませんが、正しいセルにリダイレクトする方法を知っています。
ルータはステートレスで、routes
データベースから読み取ることはありません。つまり、データベースとのやり取りはすべて Rails モノリスから行われます。このアーキテクチャは、トラフィックの少ないデータベースを地域間で複製できるようにすることで、地域もサポートしています。
ユーザーは直接Cellsの概念に触れることはありませんが、代わりに選択したOrganizationsによって異なるデータを見ることができます。Organizationsはアプリケーションの分離を強化するために導入される新しいエンティティで、Organizationは1つのCellにしか存在できないため、どのリクエストをどのCellにルーティングするかを決めることができます。
相違点
この提案と学習経路を持つ提案の主な違いは、この提案が常にいずれかのCellにリクエストを送信することです。リクエストが処理できない場合、リクエストは関連するヘッダとともにバウンスバックされます。このため、リクエストはバッファリングされる必要があります。リクエストのデコードは、URI経由でもRailsによるリクエスト本文経由でも可能です。これは、各リクエストが複数回送信され、結果として複数回処理される可能性があることを意味します。
with learning routesの提案では、ルーティング可能な情報は常にURIにエンコードされ、ルータはプリフライトリクエストを送信します。
図でのまとめ
これは、ユーザーのリクエストがDNS経由で最も近いルーターにルーティングされ、ルーターがリクエストを送信するセルを選択する様子を示しています。
詳細
これは、ルーターが実際にどのセルにもリクエストを送信できることを示しています。ユーザーは地理的に最も近いルーターを取得します。 ```mermaid graph TD; user((User)); dns[DNS]; router_us(Router); router_eu(Router); cell_us0{Cell US0}; cell_us1{Cell US1}; cell_eu0{Cell EU0}; cell_eu1{Cell EU1}; user-->dns; dns-->router_us; dns-->router_eu; subgraph Europe router_eu-->cell_eu0; router_eu-->cell_eu1; end subgraph United States router_us-->cell_us0; router_us-->cell_us1; end router_eu-.->cell_us0; router_eu-.->cell_us1; router_us-.->cell_eu0; router_us-.->cell_eu1; ```さらに詳細
これはデータベースを示しています。`gitlab_users` と`gitlab_routes` は米国リージョンにのみ存在しますが、他のリージョンにもレプリケートされます。レプリケーションに矢印がないのは、図を読むのが難しいからです。 ```mermaid graph TD; user((User)); dns[DNS]; router_us(Router); router_eu(Router); cell_us0{Cell US0}; cell_us1{Cell US1}; cell_eu0{Cell EU0}; cell_eu1{Cell EU1}; db_gitlab_users[(gitlab_users Primary)]; db_gitlab_routes[(gitlab_routes Primary)]; db_gitlab_users_replica[(gitlab_users Replica)]; db_gitlab_routes_replica[(gitlab_routes Replica)]; db_cell_us0[(gitlab_main/gitlab_ci Cell US0)]; db_cell_us1[(gitlab_main/gitlab_ci Cell US1)]; db_cell_eu0[(gitlab_main/gitlab_ci Cell EU0)]; db_cell_eu1[(gitlab_main/gitlab_ci Cell EU1)]; user-->dns; dns-->router_us; dns-->router_eu; subgraph Europe router_eu-->cell_eu0; router_eu-->cell_eu1; cell_eu0-->db_cell_eu0; cell_eu0-->db_gitlab_users_replica; cell_eu0-->db_gitlab_routes_replica; cell_eu1-->db_gitlab_users_replica; cell_eu1-->db_gitlab_routes_replica; cell_eu1-->db_cell_eu1; end subgraph United States router_us-->cell_us0; router_us-->cell_us1; cell_us0-->db_cell_us0; cell_us0-->db_gitlab_users; cell_us0-->db_gitlab_routes; cell_us1-->db_gitlab_users; cell_us1-->db_gitlab_routes; cell_us1-->db_cell_us1; end router_eu-.->cell_us0; router_eu-.->cell_us1; router_us-.->cell_eu0; router_us-.->cell_eu1; ```変更の概要
- ユーザーデータ(プロファイル設定、認証情報、個人アクセストークンを含む)に関連するテーブルが、
gitlab_users
スキーマに分解されました。 -
routes
テーブルはgitlab_routes
スキーマに分解されます。 -
application_settings
(およびおそらく他のいくつかのインスタンスレベルのテーブル)は、gitlab_admin
スキーマに分解されます。 - 新しいカラム
routes.cell_id
がroutes
テーブルに追加されます。 - どのセルにリクエストをルーティングするかを選択する新しいルーターサービスが存在します。
- GitLabには組織という新しい概念が導入され、ユーザーは “default organization “を選択することができ、これはユーザーレベルの設定となります。デフォルトの組織は、
/dashboard
のような曖昧なルートから、/organizations/my-organization/-/dashboard
のような組織スコープのルートにユーザーをリダイレクトするために使われます。レガシーユーザーは、Cell US0
のグローバルリソースを使用し続けることができる特別なデフォルト組織を持つことになります。既存のネームスペースはすべて、最初はこの公開組織に移動します。 - セルが所有していない
routes.cell_id
のリクエストを受け取った場合、ルーターが正しいセルに リクエストを送ることができるように、302
とX-Gitlab-Cell-Redirect
ヘッダーを返します。正しいセルはまた、このリクエストがセルを覚えておくためにどの ようにキャッシュされるべきかについての情報を含むヘッダーX-Gitlab-Cell-Cache
を設定することができます。例えば、リクエストが/gitlab-org/gitlab
の場合、ヘッダーは/gitlab-org/* => Cell US0
をエンコードします(例えば、/gitlab-org/
で始まるリクエストは常に にルーティングされます)。Cell US0
- セルが(キャッシュから)どのセルにリクエストを送るかわからないときは、 単にその領域内のランダムなセルを選ぶだけです。
-
gitlab_users
とgitlab_routes
への書き込みはUS
リージョンのプライマリ PostgreSQL サーバに送信されますが、読み込みは同じリージョン内のレプリカから行うことができます。このため、これらの書き込みにはレイテンシが発生しますが、GitLabの他の部分と比較すると発生頻度は低いと思われます。
最初の反復におけるデフォルトの構成についての詳細な説明
すべてのユーザーは、ユーザー設定でコントロールできる新しいカラムusers.default_organization
。GitLab.com Public
組織という概念を導入します。これは、すべての既存ユーザーのデフォルトの組織として設定されます。この組織では、ユーザーはCell US0
のすべての名前空間(例えば、私たちのオリジナルの GitLab.com インスタンス)のデータを見ることができます。この振る舞いは、既存のユーザーには見えないようにすることができます。/dashboard
のようなグローバルページを表示しているときに、それが組織にスコープされていることすら知らされないようにすることができます。
GitLab.com Public
以外のデフォルト組織を持つ新規ユーザーは、異なるユーザーエクスペリエンスを持つことになり、読み込むすべてのページが単一の組織にのみスコープされていることを完全に認識することになります。このようなユーザーは、/dashboard
のようなグローバルページを読み込むことができず、/organizations/<DEFAULT_ORGANIZATION>/-/dashboard
にリダイレクトされてしまいます。これはレガシーAPIの場合も同様で、このようなユーザーは組織にスコープされたAPIしか使用できない可能性があります。
管理エリア設定の詳細
私たちは、管理エリアの設定を維持したり同期させたりすることは、イライラさせ、苦痛を伴うと信じています。そのため、これを避けるために、すべての管理エリアの設定を分解し、gitlab_admin
スキーマで共有します。このスキーマは書き込みトラフィックがほとんどないため、(他の共有スキーマと同様に)安全です。
異なるセルが異なる設定を必要とする場合(例えばElasticsearchのURLなど)には、セルごとに動的に設定できるように、関連するapplication_settings
の行でテンプレート化されたフォーマットを使用することにします。また、それが難しい場合は、per_cell_application_settings
という新しいテーブルを導入し、セルごとに異なる設定ができるように、セルごとに1行を持つようにします。このテーブルもgitlab_admin
スキーマの一部として共有され、一元的に管理することができます。
長所
- ルーターはステートレスで、多くの地域に住むことができます。エニーキャストDNSを使用して、ユーザーに最も近い地域に解決します。
- セルは間違ったセルの名前空間に対するリクエストを受信しても、ユーザーは正しいレスポンスを得ることができます。また、次のリクエストが正しいセルに送信されるようにするルータでのキャッシュにより、次のリクエストは正しいセルに送信されます。
- コードの大部分はまだ
gitlab
Rails コードベースにあります。ルーターは GitLab の URL がどのように構成されているかを理解する必要はありません。 -
gitlab_users
、gitlab_routes
、gitlab_admin
を読み書きする責任はまだ Rails にあるので、ドメインモデルを分離して新しいインターフェースを構築する必要があるサービスを抽出するのに比べて、Rails アプリケーションには最小限の変更で済むことになります。 - 別個のルーティングサービスと比べて、RailsアプリケーションはURLを正しいセルにマッピングする方法についてより複雑なルールをエンコードすることができ、既存のAPIエンドポイントでも機能する可能性があります。
- 新しいインフラ (ルーターだけ) はすべてオプションで、シングルセルのセルフマネージドインストールではルーターを実行する必要すらなく、他に新しいサービスもありません。
短所
-
gitlab_users
gitlab_routes
、gitlab_admin
データベースはリージョンをまたいで複製する必要があり、書き込みはリージョンをまたぐ必要があるかもしれません。実現可能かどうかを判断するために、関連テーブルの書き込みTPSを分析する必要があります。 - 多くの異なる Cell からデータベースへのアクセスを共有するということは、すべての Cell が Postgres スキーマレベルで結合されるということであり、これはデータベーススキーマの変更をすべての Cell のデプロイと同期して慎重に行う必要があることを意味します。このため、私たちがコントロールする API を持つ共有サービスによるアーキテクチャと比較して、Cell を密接に類似したバージョンに保つことが制限されます。
- ほとんどのデータは適切なリージョンに保存されますが、別のリージョンからプロキシされるリクエストもあり、これはある種のコンプライアンスにとってイシューになる可能性があります。
-
gitlab_users
、gitlab_routes
データベースのデータは、すべてのリージョンで複製される必要があり、これは特定の種類のコンプライアンスにとってイシューとなる可能性があります。 - 多種多様なURL(例えば、ロングテール)を取得する場合、ルーターキャッシュは非常に大きくする必要があるかもしれません。そのような場合、ユーザークッキーに第2レベルのキャッシュを実装し、頻繁にアクセスされるPagesが常に最初に正しいセルに行くようにする必要があるかもしれません。
- 複数のセルから
gitlab_users
、gitlab_routes
、共有データベースアクセスを持つことは、複数のセルから呼び出されるサービスを抽出することと比べると、珍しいアーキテクチャの決定です。 - GraphQL URLのキャッシュ可能な要素を見つけることができない可能性が非常に高く、既存のGraphQLエンドポイントは
routes
テーブルにないidに大きく依存していることが多いため、セルはどのセルがデータを持っているかを必ずしも知ることができません。そのため、/api/organizations/<organization>/graphql
のようにパスに組織のコンテキストを含めるようにGraphQLコールを更新する必要があるでしょう。 - このアーキテクチャは、実装されたエンドポイントが、与えられたセル上で容易にアクセスできるデータにのみアクセスできることを意味し、多くのセルからの情報を集約することは考えにくい。
- 未知のルートはすべて最新のデプロイに送信されます。
Cell US0
と仮定します。これは新しく追加されたエンドポイントは最新のセルにしか解読できないためです。このセルは後で、与えられたリクエストに対応できる正しいセルにリダイレクトすることができます。リクエストの処理が重いので、いくつかのセルはそのためにかなりの量のトラフィックを受け取るかもしれません。
データベースの設定例
gitlab_users
、gitlab_routes
、gitlab_admin
の共有データベースを扱いながら、gitlab_main
、gitlab_ci
の専用データベースを持つことは、config/database.yml
を使用する方法ですでに処理できるはずです。また、gitlab_users
とgitlab_routes
に対して単一の米国プライマリを持つ一方で、EU専用のレプリカを扱うこともできるはずです。以下は、上記のCellアーキテクチャのデータベース設定の一部のスニペットです。セル US0
```yaml
# config/database.yml
production:
main:
host: postgres-main.cell-us0.primary.consul
load_balancing:
discovery: postgres-main.cell-us0.replicas.consul
ci:
host: postgres-ci.cell-us0.primary.consul
load_balancing:
discovery: postgres-ci.cell-us0.replicas.consul
users:
host: postgres-users-primary.consul
load_balancing:
discovery: postgres-users-replicas.us.consul
routes:
host: postgres-routes-primary.consul
load_balancing:
discovery: postgres-routes-replicas.us.consul
admin:
host: postgres-admin-primary.consul
load_balancing:
discovery: postgres-admin-replicas.us.consul
```
セル EU0
```yaml
# config/database.yml
production:
main:
host: postgres-main.cell-eu0.primary.consul
load_balancing:
discovery: postgres-main.cell-eu0.replicas.consul
ci:
host: postgres-ci.cell-eu0.primary.consul
load_balancing:
discovery: postgres-ci.cell-eu0.replicas.consul
users:
host: postgres-users-primary.consul
load_balancing:
discovery: postgres-users-replicas.eu.consul
routes:
host: postgres-routes-primary.consul
load_balancing:
discovery: postgres-routes-replicas.eu.consul
admin:
host: postgres-admin-primary.consul
load_balancing:
discovery: postgres-admin-replicas.eu.consul
```
リクエストフロー
-
gitlab-org
はトップレベルの名前空間で、GitLab.com Public
組織のCell US0
に存在します。 -
my-company
はトップレベルの名前空間で、my-organization
組織のCell EU0
に存在します。
の一部である有料ユーザーのエクスペリエンスです。my-organization
このようなユーザーは、デフォルトの組織が/my-organization
に設定され、この組織以外のグローバルルートを読み込むことができません。他のプロジェクト/ネームスペースをロードすることはできますが、ページ上部のMR/ToDo/イシューのカウントは最初の反復では正しく入力されません。ユーザーはこの制限を認識します。
ログイン中に/my-company/my-project
に移動します。
- ユーザーはヨーロッパにいるため、DNSはヨーロッパのルーターに解決します。
- ルーターのキャッシュなしで
/my-company/my-project
。Cell EU1
-
Cell EU1
は/my-company
を持っていませんが、ルータがその中に住んでいることを知ってCell EU0
いるので、ルータをリダイレクトしてCell EU0
-
Cell EU0
にリダイレクトし、正しいレスポンスを返します。/my-company/* => Cell EU0
- ルータは
/my-company/*
にマッチするリクエストパスをキャッシュし、覚えています。Cell EU0
ログインしていないときに/my-company/my-project
に移動します。
- ユーザーはヨーロッパにいるため、DNSはヨーロッパのルーターに解決します。
- ルーターは
/my-company/*
をまだキャッシュしていないので、ランダムに選択します。Cell EU1
-
Cell EU1
ログインフローを経由して - それでも彼らはルーターのキャッシュなしで
/my-company/my-project
、ルーターはランダムなセルを選択します。Cell EU1
-
Cell EU1
は/my-company
を持っていませんが、ルータがその中に住んでいることを知ってCell EU0
いるので、ルータをリダイレクトしてCell EU0
-
Cell EU0
にリダイレクトし、正しいレスポンスを返します。/my-company/* => Cell EU0
- ルータは
/my-company/*
にマッチするリクエストパスをキャッシュし、覚えています。Cell EU0
最後のステップの後、/my-company/my-other-project
。
- ユーザーはヨーロッパにいるため、DNSはヨーロッパのルーターに解決します。
- ルーターのキャッシュには
/my-company/* => Cell EU0
があるので、ルーターは以下を選択します。Cell EU0
-
Cell EU0
は正しいレスポンスとキャッシュヘッダを返します。
最後のステップの後、/gitlab-org/gitlab
。
- ユーザーはヨーロッパにいるため、DNSはヨーロッパのルーターに解決します。
- ルーターにはこのURLのキャッシュ値がないため、ランダムに
Cell EU0
-
Cell EU0
にリダイレクトします。Cell US0
-
Cell US0
は正しいレスポンスとキャッシュヘッダを返します。
この場合、ユーザーは「デフォルトの組織」ではないので、TODOカウンターには典型的なTODOは含まれません。このことをUIのどこかで強調表示することもできます。将来的には、デフォルトの組織からTODOを取得できるようになるかもしれません。
にナビゲートします。/
- ユーザーはヨーロッパにいるため、DNSはヨーロッパのルーターに解決します。
- ルーターに
/
ルート用のキャッシュがない(特にRailsがこのルートをキャッシュするように指示したことがない)。 - ルータは
Cell EU0
をランダムに選択します。 - Railsアプリケーションは、ユーザーのデフォルト組織が
/my-organization
であることを知っているので、ユーザーを次のようにリダイレクトします。/organizations/my-organization/-/dashboard
- ルータは
/organizations/my-organization/*
のキャッシュ値を持っているので、リクエストをPOD EU0
-
Cell EU0
にリクエストを送ります。/organizations/my-organization/-/dashboard
は現在あるのと同じダッシュボードビューですが、UIで明確に組織にスコープされています。 - ユーザーには(オプションで)、このページのデータはデフォルトの組織のものであり、デフォルトの組織が正しくない場合は変更できるというメッセージが表示されます。
にナビゲートします。/dashboard
Railsアプリケーションはすでに/
、ダッシュボードのページにリダイレクトしているため、上記のページと同様に、/organizations/my-organization/-/dashboard
。
ログインした状態で/not-my-company/not-my-project
に移動します (ただし、このプロジェクト/グループは非公開なので、アクセス権はありません)。
- ユーザーはヨーロッパにいるため、DNSはヨーロッパのルーターに解決します。
- ルーターは
/not-my-company
がCell US1
に住んでいることを知っているので、このルーターにリクエストを送ります。 - ユーザーはアクセスできないので、
Cell US1
は 404 を返します。
新しいトップレベル・ネームスペースを作成します。
ユーザは、ネームスペースをどの組織に所属させるかを尋ねられます。ユーザが選択した場合、そのネームスペースmy-organization
は .NET の他のすべてのネームスペースと同じセルに表示さ my-organization
れます。 ユーザが何も選択しなかった場合、デフォルトはGitLab.com Public
になり、ユーザはこのネームスペースが既存の組織から分離され、1 つのページで両方のデータを表示できないことがわかります。
GitLabチームメンバーの経験/gitlab-org
このようなユーザーはレガシーユーザーとみなされ、デフォルトの組織はGitLab.com Public
に設定されています。これは実際には存在しない「メタ」組織ですが、Railsアプリケーションはこの組織を解釈することで、/dashboard
のようなレガシーなグローバル機能を使用して、Cell US0
にある名前空間全体のデータを参照することが許可されていることを知っています。Railsバックエンドは、/dashboard
のような曖昧なルートをレンダリングするデフォルトのセルはCell US0
であることも知っています。最後に、ユーザーは/my-organization
のような別のセルにある組織に移動することができますが、移動すると、いくつかのデータ(たとえば、MRs/Issues/Todos)が欠落している可能性があることを示すメッセージが表示されます。
ログインしていないときに/gitlab-org/gitlab
に移動します。
- ユーザーは米国にいるため、DNSは米国のルーターに解決されます。
- ルーターは、
/gitlab-org
がCell US0
に住んでいることを知っているので、このセルにリクエストを送信します。 -
Cell US0
レスポンス
にナビゲートします。/
- ユーザーは米国にいるため、DNSは米国のルーターに解決されます。
- ルーターに
/
ルート用のキャッシュがない(特にRailsがこのルートをキャッシュするように指示したことがない)。 - ルーターは
Cell US1
をランダムに選択します。 - Railsアプリケーションはユーザーのデフォルト組織が
GitLab.com Public
であることを知っているので、ユーザーを/dashboards
にリダイレクトします(レガシーユーザーのみが/dashboard
グローバルビューを見ることができます)。 - ルーターに
/dashboard
ルート用のキャッシュがない(特にRailsがこのルートをキャッシュするように指示したことがない)。 - ルーターは
Cell US1
をランダムに選択します。 - Railsアプリケーションは、ユーザーのデフォルトの組織が
GitLab.com Public
であることを知っているので、ユーザーに/dashboards
(レガシーユーザーのみ/dashboard
グローバルビューを見ることができます)をロードさせ、ルーターにレガシーセルをリダイレクトします。Cell US0
-
Cell US0
はグローバルビューのダッシュボードページ/dashboard
を提供します。
ログインした状態で/my-company/my-other-project
にナビゲートします(ただし、このプロジェクトは非公開なので、彼らはアクセスできません)。
404が表示されます。
認証されていないユーザーの体験
/dashboard
のようなグローバルルートがログインページにリダイレクトされる以外は、フローは認証済みユーザーと同様です。
新規顧客がサインアップ
すでに組織に属しているのか、それとも組織を作りたいのかを尋ねられます。どちらも選択しない場合は、デフォルトのGitLab.com Public
。
組織は、1つのセルから別のセルに移動されます
TODO
URLに名前空間を含まないGraphQL/APIリクエスト
TODO
最近のイシュー/MRを記憶する検索バーのオートコンプリート・サジェスト機能
TODO
グローバル検索
TODO
管理者
/admin
ページを読み込みます。
- ルーターがランダムなセルを選択
Cell US0
- セルUS0がユーザーをリダイレクト
/admin/cells/cellus0
- セル US0 は Admin Area ページをレンダリングし、
/admin/cellss/cellus0/* => Cell US0
をキャッシュするためのキャッシュヘッダも返します。Admin Area ページは、ユーザが選択できる他のセルを示すドロップダウンリストを含み、クエリパラメータを変更します。
Postgres の Admin Area 設定は分岐を避けるためにすべてのセルで共有されますが、これらのページから生成される動的なデータとオペレータが特定のセルを表示したい場合があるため、どのセルが Admin Area ページを提供しているかを URL と UI で明確にします。
解決すべきその他の技術的問題
全セル間でのユーザーセッションの複製
現在、ユーザーセッションはRedisに保存されていますが、各セルは独自のRedisインスタンスを持つことになります。私たちはすでにセッション専用のRedisインスタンスを使っているので、gitlab_users
PostgreSQLデータベースのように、これをすべてのセルで共有することも考えられます。しかし、同じリージョンからセッションをフェッチしたいので、レイテンシを考慮することが重要です。
代替案として、ユーザーセッションをすべてのセッションデータをエンコードするJWTペイロードに移動することもできますが、これには欠点があります。例えば、セッションがユーザーによって管理されるJWTにある場合、パスワードが変更されたときやその他の理由でユーザーセッションを失効させることは困難です。
どのように Cells 間をマイグレーションするのですか?
セル間でデータをマイグレーションするには、すべてのデータストアを要因にする必要があります:
- PostgreSQL
- Redis 共有ステート
- Gitaly
- Elasticsearch
タイミング攻撃で非公開グループの存在を漏らすことは可能ですか?
EUにルーターがあり、EUのルーターがデフォルトでEUにあるCellにリダイレクトすることを知っている場合、そのレイテンシ(仮に10msとします)を知っています。今、あなたのリクエストがバウンスバックされ、異なるレイテンシを持つUSにリダイレクトされた場合(ラウンドトリップは約60ミリ秒であると仮定します)、あなたは404がUSセルによって返されたことを推測し、あなたの404が実際には403であることを知ることができます。
このことは、実際に異なる地域のセルを実装するまで延期することができます。このようなタイミング攻撃は、今日の権限チェックの方法で理論的にはすでに可能ですが、タイミングの違いはおそらく検出するには小さすぎるでしょう。
このリスクを軽減する一つのテクニックは、ルーターがセルから404を返 すリクエストにランダムな遅延を追加することかもしれません。
ランナーはすべてのセルで共有されるべきですか?
2つの選択肢がありますが、どちらが簡単か決めましょう:
- ランナー登録テーブルとキューイングテーブルを分解し、すべてのセルで共有すること。これはスケーラビリティに影響を与えるかもしれません。また、グループ/プロジェクト・ランナーを含めるかどうかを検討する必要があります。これらは共有する必要がある高トラフィック・テーブルなので、スケーラビリティの懸念があるかもしれません。
- Runnerはセルごとに登録されますが、おそらくセルごとに別々のRunnerを持つか、あるいは多くのセルに同じRunnerを登録することになるでしょう。
すべてのセルで競合しない一意のIDを保証するには?
このプロジェクトでは、少なくともネームスペースとプロジェクトがすべてのセルで一意のIDを持つことを想定しています。これらのテーブルは異なるデータベースにまたがっているため、一意のIDを保証するには新しいソリューションが必要になります。一意なIDが必要なテーブルは他にもあるでしょうし、GraphQLや他のAPIのルーティングをどのように解決するか、また他の設計目標によっては、主キーがすべてのテーブルで一意であることが望ましいと判断されるかもしれません。