GitLab Cells 开发指南
关于 GitLab Cells 的背景,请参考 设计文档。
可用的 Cells / 组织架构
以下是与 Cells 和 Organizations 相关的可用架构:
| Schema | Description |
|---|---|
gitlab_main (已弃用) |
正在被 gitlab_main_cell 替代,用于构建 Cells 架构。 |
gitlab_main_cell |
将重命名为 gitlab_main_org。用于 main: 数据库中所有属于 Organization 的表。例如 projects 和 groups |
gitlab_main_cell_setting |
main: 数据库中所有与 cell 设置相关的表。例如 application_settings。这些 cell 本地表不应有任何来自/到组织表的外键引用。 |
gitlab_main_clusterwide (已弃用) |
main: 数据库中所有需要在整个集群中存在(或部分行)的表,在 Cells 架构中。例如 plans。对于 Cells 1.0 架构,没有真正的集群级表,因为每个 cell 都有自己的数据库。实际上,这些表仍将存储在每个 cell 中。 |
gitlab_main_cell_local |
main: 数据库中与每个 cell 特有功能相关的表。例如 zoekt_nodes 或 shards。这些 cell 本地表不应有任何来自/到组织表的外键引用。 |
gitlab_ci |
用于 ci: 数据库中所有属于 Organization 的表。例如 ci_pipelines 和 ci_builds |
gitlab_ci_cell_local |
ci: 数据库中与每个 cell 特有功能相关的表。例如 instance_type_ci_runners 或 ci_cost_settings。这些 cell 本地表不应有任何来自/到组织表的外键引用。 |
gitlab_main_user |
所有用户相关表的架构,例如 users、emails 等。大多数用户功能都是组织级别的,应使用 gitlab_main_cell(例如在 issue 上评论)。对于非组织级别的用户功能,使用此架构。此架构上的表必须严格属于某个用户。 |
大多数表需要定义一个 分片键。
要了解现有表的分类,可以使用 此仪表板。
分配架构后,合并请求管道可能因以下一个或多个原因失败,可通过遵循相关指南解决:
如果功能可以是集群级的,应选择什么架构?
gitlab_main_clusterwide 架构现已弃用。
我们将要求团队根据需要将表从 gitlab_main_clusterwide 更新为 gitlab_main_cell。
这需要为这些表添加分片键,并可能需要
对相关功能进行额外更改,将其范围限定在组织级别。
集群级功能 强烈不推荐, 并且 没有计划执行任何集群级同步。
请从可用的 GitLab 架构列表中选择其他架构。
我们期望大多数表使用 gitlab_main_cell 架构,特别是如果
表与 projects 或 namespaces 相关。
另一个替代方案是 gitlab_main_cell_local 架构。
咨询 Tenant Scale 团组: 如果您认为需要集群级功能,请向 Tenant Scale 团组寻求设计输入。 以下是需要考虑的一些因素:
- 该功能是否可以限定在组织(或更低)级别?
- 相关功能必须在多个 cell 上工作,而不仅仅是传统 cell。
- 相关功能如何在多个组织和 cell 之间扩展?
- 数据将如何存储?
- 组织将如何一致地引用数据? 您可以使用全局唯一标识符吗?
- 数据是否需要在不同的 cell 之间保持一致?
- 不要使用数据库表来存储 静态数据。
创建新架构
架构默认要求分片键,因为功能默认应限定在组织级别。
# db/gitlab_schemas/gitlab_ci.yaml
require_sharding_key: true
sharding_root_tables:
- projects
- namespaces
- organizations将 require_sharding_key 设置为 true 意味着分配给该架构的表
需要设置 sharding_key。
您还需要配置允许的 sharding_root_tables 列表,这些表可用作此架构中表的分片键。
静态数据
问题:使用数据库表存储静态数据。 但是主键不是静态的,因为它使用自增序列。 这意味着主键不是全局一致的。
对此不一致主键的引用会产生问题,因为 引用会在 cell / 组织之间冲突。
示例:给定 Cell 上的 plans 表有以下数据:
id | name | title
----+------------------------------+----------------------------------
1 | default | Default
2 | bronze | Bronze
3 | silver | Silver
5 | gold | Gold
7 | ultimate_trial | Ultimate Trial
8 | premium_trial | Premium Trial
9 | opensource | Opensource
4 | premium | Premium
6 | ultimate | Ultimate
10 | ultimate_trial_paid_customer | Ultimate Trial for Paid Customer
(10 rows)在另一个 cell 上,plans 表对相同 name 有不同的 id:
id | name | title
----+------------------------------+------------------------------
1 | default | Default
2 | bronze | Bronze
3 | silver | Silver
4 | premium | Premium
5 | gold | Gold
6 | ultimate | Ultimate
7 | ultimate_trial | Ultimate Trial
8 | ultimate_trial_paid_customer | Ultimate Trial Paid Customer
9 | premium_trial | Premium Trial
10 | opensource | Opensource然后,plans.id 列被用作 gitlab_subscriptions 表中 hosted_plan_id 列的引用。
解决方案:使用全局唯一引用,而不是数据库序列。 如果可能,在应用程序代码中硬编码静态数据,而不是使用数据库。
在这种情况下,可以删除 plans 表,并替换为固定模型:
class Plan
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveRecord::FixedItemsModel::Model
ITEMS = [
{:id=>1, :name=>"default", :title=>"Default"},
{:id=>2, :name=>"bronze", :title=>"Bronze"},
{:id=>3, :name=>"silver", :title=>"Silver"},
{:id=>4, :name=>"premium", :title=>"Premium"},
{:id=>5, :name=>"gold", :title=>"Gold"},
{:id=>6, :name=>"ultimate", :title=>"Ultimate"},
{:id=>7, :name=>"ultimate_trial", :title=>"Ultimate Trial"},
{:id=>8, :name=>"ultimate_trial_paid_customer", :title=>"Ultimate Trial for Paid Customer"},
{:id=>9, :name=>"premium_trial", :title=>"Premium Trial"},
{:id=>10, :name=>"opensource", :title=>"Opensource"}
]
attribute :id, :integer
attribute :name, :string
attribute :title, :string
endhosted_plan_id 列也将更新为引用固定模型的 id 值。
硬编码静态数据的示例包括:
Cells 路由
即将推出,关于如何将请求路由到您组织 cell 的指南。