GitLab Cells 개발 가이드
GitLab Cells의 배경에 대해서는 디자인 문서를 참조하세요.
gitlab_main_cell
또는 gitlab_main_clusterwide
스키마 중 하나를 선택합니다.
사용 사례에 따라 기능이 셀 내 또는 클러스터 전역일 수 있으므로 해당 기능에 사용되는 테이블도 적절한 스키마를 사용해야 합니다.
테이블에 적절한 스키마를 선택할 때 다음 가이드라인을 고려하세요:
-
gitlab_main_cell
을 기본으로 설정: 우리는 대부분의 테이블이 기본적으로gitlab_main_cell
스키마에 할당될 것으로 예상합니다. 테이블의 데이터가projects
또는namespaces
와 관련이 있는 경우 이 스키마를 선택하세요. - 테넌트 스케일 그룹과 상의: 특정 테이블에
gitlab_main_clusterwide
스키마가 더 적합하다고 생각하는 경우 테넌트 스케일 그룹의 승인을 얻으세요. 이것은 스케일링 영향을 미칠 수 있으며 스키마 선택을 재고해야 하기 때문에 중요합니다.
gitlab_main_clusterwide
스키마를 사용하는 테이블은 다른/모든 셀로 복제하기 위해 추가 작업이 필요합니다.
복제 전략은 각각의 경우에 따라 다를 것이지만 내부 API를 활용할 것입니다.
충돌을 방지하기 위해 응용프로그램도 수정되어 쓰기를 제한할 수 있습니다.
우리는 또한 팀에게 테이블을 필요에 따라 gitlab_main_clusterwide
에서 gitlab_main_cell
로 업데이트하도록 요청할 수 있으며, 이때 해당 테이블에 분할 키를 추가해야 할 수도 있습니다.
기존 테이블이 어떻게 분류되어 있는지 이해하려면 이 대시보드를 사용할 수 있습니다.
스키마가 할당된 후에는 병합 요청 파이프라인이 다음과 같은 이유 중 하나 이상으로 실패할 수 있으며, 이에 대한 가이드라인을 따르면 문제를 해결할 수 있습니다:
모든 셀-로컬 테이블에 대한 분할 키 정의
다음 gitlab_schema
를 갖는 모든 테이블은 “셀-로컬”로 간주됩니다:
gitlab_main_cell
gitlab_ci
gitlab_sec
새로 생성된 셀-로컬 테이블은 해당 테이블의 db/docs/
파일에 정의된 sharding_key
를 가져야 합니다.
분할 키의 목적은 조직 격리 청사진에서 문서화되어 있지만, 간단히 말해서 이 열은 데이터베이스에서 특정 행을 소유하는 조직을 결정하는 표준 방식을 제공하는 데 사용됩니다. 나중을 위해 이 열은 데이터를 조직 경계를 넘지 않도록 제약 조건을 강제하는 데 사용될 것입니다. 또한 셀 간에 데이터 이관을 일관된 방식으로 제공하기 위해 사용될 것입니다.
외래 키의 실제 이름은 무엇이든지 상관없지만 projects
또는 groups
의 행을 참조해야 합니다. 선택한 sharding_key
열은 null이 아니어야 합니다.
다중 sharding_key
를 설정하여 nullable 열을 허용하는 것도 허용됩니다. 다만, 해당 테이블에 대해 적어도 하나의 키가 null이 아니어야 함을 올바르게 보장하는 체크 제약 조건이 있어야 합니다. 이러한 제약 조건을 생성하는 방법에 대한 지침은 다중 열에 대한 NOT NULL
제약 조건을 참조하세요.
다음은 유효한 분할 키의 예입니다:
-
테이블 항목은 프로젝트에만 속함:
sharding_key: project_id: projects
-
테이블 항목은 프로젝트에 속하며, 외래 키는
target_project_id
:sharding_key: target_project_id: projects
-
테이블 항목은 네임스페이스/그룹에만 속함:
sharding_key: namespace_id: namespaces
-
테이블 항목은 네임스페이스/그룹에만 속하며, 외래 키는
group_id
:sharding_key: group_id: namespaces
-
테이블 항목은 네임스페이스 또는 프로젝트에 속함:
sharding_key: project_id: projects namespace_id: namespaces
분할 키는 불변해야 합니다
분할 키 선택은 항상 불변해야 합니다. 따라서 기능에 따라 데이터를 이동할 수 있는 사용자 경험이 필요한 경우 새로운 행을 생성하도록 이동 기능을 재설계해야 할 수 있습니다. 이러한 사례의 예는 이슈 이동 기능에서 볼 수 있습니다. 이 기능은 실제로 기존 issues
행의 project_id
열을 변경하는 것이 아니라 새 issues
행을 생성하고 데이터베이스에서 원래 issues
행에 링크를 생성합니다. 조직 데이터를 이동할 수 있어야 하는 특히 어려운 기존 기능이 있는 경우 테넌트 스케일 팀에 연락하여 분할 키를 어떻게 관리할지에 대한 옵션들을 논의해야 할 것입니다.
프로젝트 및 네임스페이스에 대해 동일한 분할 키를 사용하기
개발자는 또한 테이블에서 사용되는 기능이 그룹 및 프로젝트 통합 청사진을 따르는 경우에는 테이블이 속할 수 있는 프로젝트에 대해 namespace_id
만 사용할 수 있도록 선택할 수 있습니다. 이 경우 namespace_id
는 ProjectNamespace
의 ID여야 하며 해당 네임스페이스가 속한 그룹의 ID는 아니어야 합니다.
organization_id
를 분할 키로 사용하기
일반적으로 project_id
또는 namespace_id
가 가장 일반적인 분할 키입니다.
그러나 테이블이 프로젝트 또는 네임스페이스에 속하지 않는 경우가 있습니다.
이러한 경우 organization_id
는 분할 키의 옵션입니다. 다만, 아래 가이드라인을 따라야 합니다:
-
sharding_key
열은 여전히 불변해야 합니다. - 루트 레벨 모델에만
organization_id
를 추가합니다(예:namespaces
). - 이러한 테이블에는 그룹 또는 프로젝트와 관련된 데이터가 포함되어서는 안 됩니다(또는 그룹 또는 프로젝트에 속하는 레코드).
대신
project_id
또는namespace_id
를 사용하세요. - 많은 행을 포함하는 테이블은 좋은 후보가 아닙니다.
- 이 테이블을 참조하는 다른 테이블이 있는 경우 참조 테이블 레코드가 다른 조직으로 이동해도 응용프로그램이 계속 작동해야 합니다.
만약 organization_id
가 분할 키로서 최선의 선택이라고 생각한다면, 테넌트 스케일 그룹의 승인을 얻으세요.
이것은 데이터 이관에 대한 영향이 있을 수 있으며 분할 키 선택을 재고해야 할 수 있기 때문에 중요합니다.
예를 들어, 이 이슈는 기존 테이블에 organization_id
를 분할 키로 추가했습니다.
desired_sharding_key
정의하여 sharding_key
를 자동으로 다시 채우기
우리는 sharding_key
가 없는 수백 개의 테이블에 sharding_key
를 다시 채워넣어야 합니다.
이 프로세스는 새로운 열을 추가하고, 데이터를 관련 테이블에서 백업한 다음에 인덱스, 외래 키 및 비-널(Not-Null) 제약 조건을 추가하는 것과 같은 병합 요청을 만들어야 합니다.
개발자들의 반복적인 노력을 최소화하기 위해, 우리는이 특정 테이블에 대한 sharding_key
를 다시 채울 방법을 간결하게 선언적으로 설명하는 방법을 도입했습니다. 이 내용은 나중에 필요한 모든 병합 요청을 자동으로 생성하는 데 사용될 것입니다.
desired_sharding_key
의 예는 https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139336에 추가되었으며 다음과 같습니다:
--- # db/docs/security_findings.yml
table_name: security_findings
classes:
- Security::Finding
...
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: scanner_id
table: vulnerability_scanners
table_primary_key: id # 선택 사항. 기본값은 'id'
sharding_key: project_id
belongs_to: scanner
이 YAML 데이터가 어떻게 사용될지 가장 잘 이해하기 위해 수동으로 생성한 병합 요청에 GraphQL에서 매핑할 수 있습니다.
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136800.
아이디어는 이것을 자동으로 생성하는 것입니다. YAML의 내용은 배치된 백그라운드 마이그레이션에서 sharding_key
를 자동으로 채울 부모 테이블 및 그것의 sharding_key
를 지정합니다. 또한 before_save
에서 sharding_key
를 자동으로 채울 모델에 추가될 belongs_to
관계도 지정합니다.
부모 테이블에 desired_sharding_key
가 있는 경우 desired_sharding_key
정의
기본적으로 desired_sharding_key
구성은 선택한 sharding_key
가 부모 테이블에 있는지 확인합니다.
그러나, 부모 테이블에도 desired_sharding_key
구성이 있고, 자체적으로 다시 채워넣기를 기다리고 있는 경우, awaiting_backfill_on_parent
필드를 포함해야 합니다.
예를 들어:
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: package_file_id
table: packages_package_files
table_primary_key: id # 선택 사항. 기본값은 'id'
sharding_key: project_id
belongs_to: package_file
awaiting_backfill_on_parent: true
이러한 desired_sharding_key
구조가 sharding_key
를 다시 채우기에 적합하지 않은 경우가 있을 수 있습니다. 이러한 경우에는 테이블을 보유하고 있는 팀이 필요한 병합 요청을 수동으로 추가해야 합니다.
특정 테이블에서 sharding 키를 제외하는 방법
특정 테이블은 다음과 같이 sharding 키에서 제외될 수 있습니다.
exempt_from_sharding: true
테이블의 데이터베이스 사전 파일에 위와 같이 추가할 수 있습니다. 이것은 다음과 같이 사용할 수 있습니다.
- .com 데이터베이스에 데이터가 없기 때문에 JiHu 특정 테이블. !145905
-
operations_feature_flag_scopes
와 같이 곧 삭제할 예정인 테이블. !147541 - 각 셀에서 세포 작업을 지원하는 셀당 반드시 필요한 테이블, 셀당 고유 데이터가 있는 경우이지만 sharding 키가 정의될 수 없는 경우. 예를 들어,
zoekt_nodes
.
sharding 키 요구 사항에서 제외된 테이블은 또한 진행 대시보드에 나타나지 않습니다.
제외된 테이블은 데이터가 이동될 때 대상 셀의 데이터베이스에 외래 키 위반을 일으킬 수 있기 때문에 외래 키가 없거나 외래 키 참조가 느슨해서는 안 됩니다. 예 및 가능한 해결책에 대한 예제는 #471182을 참조하십시오.