스트리밍 파티션 키와 CDC 기본 키
파티션 키는 같은 키의 레코드를 같은 처리 경로로 보내 순서를 유지하는 데 사용합니다. 기본 키는 변경 로그에서 어떤 행들이 같은 레코드의 갱신인지 판단하는 메타데이터입니다. 파티션 키를 지정하는 것만으로 레코드가 중복 제거되지는 않습니다.
파티션 키의 순서 보장
장치별 측정값이나 고객별 거래처럼 같은 묶음의 순서를 유지해야 할 때 하나 이상의 열을 파티션 키로 지정합니다. 키가 없는 레코드는 내부 Kafka 토픽의 파티션에 라운드로빈 방식으로 분배될 수 있습니다. 키가 있으면 같은 키의 레코드를 같은 파티션에 보내며, Kafka는 해당 파티션에 기록된 순서를 유지합니다.
Flink 변환도 모든 키 열의 값이 같은 레코드를 같은 병렬 연산자 인스턴스로 보냅니다. 명시적으로 다시 키를 지정하지 않으면 일반적인 열 삭제나 값 덮어쓰기만으로 현재 파이프라인의 내부 라우팅이 즉시 바뀌지는 않습니다.
이 보장은 원천에서 보장하던 순서보다 강해질 수 없습니다. Very high 수집처럼 앞단에서 도착 순서를 보장하지 않는 구성의 레코드를 나중에 키로 묶어도 이미 뒤바뀐 순서를 복구하지 않습니다. 수집 모드부터 모든 중간 스트림과 변환의 조건을 함께 확인해야 합니다.
CDC 기본 키와 현재 뷰
스트림 기본 키는 중복 해소에 사용할 열들의 집합이며, 스트리밍의 순서를 정렬하는 열 목록은 아닙니다. 원시 저장 데이터와 일반 스트리밍 변환 자체를 중복 제거하는 설정도 아닙니다.
전체 저장 데이터는 변경 로그이고, CDC를 이해하는 소비자는 기본 키를 이용하여 키별로 가장 최근에 스트리밍된 행을 남기는 현재 뷰를 만듭니다. 최신 행의 값이 null이어도 그 행 전체를 유지합니다. 이전 행의 비어 있지 않은 값으로 채우는 부분 갱신 방식이 아닙니다.
삭제 열을 지정했고 최신 행의 삭제 값이 true이면 해당 키의 행을 현재 뷰에서 제외합니다.
가상 기본 키가 Key, 삭제 열이 isDeleted인 입력입니다. 위쪽 행일수록 더 최근에 들어왔습니다.
| Key | Value | isDeleted |
|---|---|---|
| Key2 | null | false |
| Key1 | thirdVal | true |
| Key2 | secondVal | false |
| Key1 | firstVal | false |
CDC 소비자의 현재 뷰는 다음과 같습니다.
| Key | Value | isDeleted |
|---|---|---|
| Key2 | null | false |
기본 키를 지정할 때는 같은 열들을 파티션 키로도 지정해야 올바른 키별 순서로 현재 뷰를 계산할 수 있습니다. 스트리밍 설정 화면에서 기본 키를 지정하면 같은 열이 파티션 키에도 자동으로 추가됩니다.
CDC를 해석하는 소비자
| 소비 경로 | 읽는 방식 |
|---|---|
| 기본 키가 있는 스트림을 온톨로지에 동기화 | 새 변경 레코드에 따라 객체를 생성, 갱신 또는 삭제합니다. |
| 아카이브 데이터셋을 Spark 변환으로 읽기 | 변환 전에 기본 키에 따라 중복을 해소한 현재 뷰를 읽습니다. |
| Dataset Preview와 Contour 등 아카이브 조회 | 대부분 Spark 작업을 사용하므로 현재 뷰로 보입니다. |
| 원시 아카이브 파일 다운로드 | 전체 변경 로그가 파일에 남아 있습니다. |
| Spark를 사용하지 않는 스트리밍 작업 및 재생 | 전체 변경 로그를 처리합니다. |
같은 스트림이라도 원시 파일, 배치 현재 뷰와 스트리밍 재생의 행 수가 같아야 하는 것은 아닙니다.
변환을 거치는 키 메타데이터
Pipeline Builder는 파티션 키와 기본 키 열의 변화를 추적하고 유효한 키를 출력 스트림의 스키마에 기록합니다.
| 변경 | 키 메타데이터의 결과 |
|---|---|
| 키 열 이름 변경 | 새 열 이름으로 키를 갱신합니다. |
| 키 열 삭제 | 해당 열을 키에서 제거합니다. |
| 키 열 값 덮어쓰기 | 새 순서나 중복 해소 의미를 자동 추론하지 않고 해당 열을 키에서 제거합니다. |
| 모든 키 열 삭제 또는 덮어쓰기 | 해당 키 전체가 사라집니다. |
| UDF | 키를 전파하지 않습니다. 필요한 키는 UDF 뒤에서 다시 지정합니다. |
| 상태 기반 변환 | 기본 키는 전파하지 않습니다. |
현재 파이프라인 내부에서 유지하는 기존 라우팅과 출력 스키마의 키 메타데이터는 구분합니다. 키 열을 삭제하거나 덮어써도 명시적으로 재키 지정하기 전까지 같은 파이프라인 안의 기존 키별 순서는 유지됩니다. 다만 유효한 키가 출력에 남지 않으면 다음 파이프라인의 순서 및 중복 해소 구성을 그대로 이어갈 수 없습니다.
덮어쓴 열을 새 키로 사용하려면 Key by를 다시 적용합니다. 재키 지정은 그 지점 이후의 처리 경로를 정하며 이전 데이터를 새 키 기준으로 다시 정렬하지 않습니다.
Key by 설정
Pipeline Builder의 스트리밍 그래프에 Key by를 추가합니다. 이 노드에서 설정한 키는 입력에 있던 키를 덮어쓰고 대체합니다.
- 파티션 키만 설정하려면
CDC mode를 끄고Key by columns만 지정합니다. 나머지 CDC 매개변수는 이 모드에서 사용할 수 없습니다. - 파티션 키와 기본 키를 함께 설정하려면
CDC mode를 켭니다. 중복 해소 열과 파티션 키 열은 같게 설정됩니다. - 삭제 표시 열이 있으면
Primary key is deleted에 선택적으로 지정합니다. - 스트리밍에서는
Primary key ordering columns를 비워 두는 것이 권장됩니다. 이 값은 배치에서 아카이브를 소비할 때의 해소 순서에 영향을 주며 스트리밍 CDC의 순서를 바꾸지 않습니다. 기존 호환성이나 특별한 배치 소비 목적에 사용하는 설정입니다.
스키마에서 파티션 키 확인
스트리밍 데이터셋의 Details에서 Schema를 열고 JSON을 확인합니다. 파티션 키 열은 fieldSchemaList의 해당 필드에 다음 메타데이터를 가집니다.
{
"customMetadata": {
"includeInPartitioning": true
}
}
찾아야 할 정확한 속성 이름은 includeInPartitioning입니다. 이 속성이 있는 열이 없으면 파티션 키가 없는 상태이며 저장 및 처리의 키별 순서를 보장할 수 없습니다. 수동 설정은 스키마의 다른 필드를 보존하면서 원하는 열의 customMetadata에 이 값을 추가하는 방식입니다.
기존 복합 키에 새 열을 추가하면 같은 값을 공유해야 하는 조건이 더 세분됩니다. 순서 보장은 모든 키 열이 같은 행 사이에만 적용되므로 이전의 더 넓은 그룹에 대한 보장은 약해질 수 있습니다. 키 그룹이 늘어나는 것과 물리적인 파티션 수 설정은 구분합니다.
스키마에서 기본 키 확인
중복 해소 열이 uniqueCol1, uniqueCol2이고 삭제 열이 isDeletedCol이면 스키마의 기본 키 부분은 다음과 같습니다.
{
"primaryKey": {
"columns": ["uniqueCol1", "uniqueCol2"],
"resolution": {
"type": "duplicate",
"duplicate": {
"resolutionStrategy": {
"type": "customStrategy",
"customStrategy": {}
},
"deletionColumn": "isDeletedCol"
}
}
}
}
기본 키가 없으면 다음과 같이 표시됩니다.
{
"primaryKey": null
}
스키마 JSON에서 해당 구성을 지정하거나 null로 바꾸어 기본 키를 제거할 수 있습니다. 수동으로 기본 키를 넣는 경우에도 같은 열을 파티션 키로 설정해야 합니다. 파티션 하나만 사용한다는 이유로 전체 파이프라인의 순서가 보장되지는 않습니다. Flink의 병렬 처리와 확장 과정도 순서에 영향을 주기 때문입니다.
키 선택 기준
순서가 중요하면 고객 ID, 이메일 ID 또는 조직 ID처럼 유지하려는 업무 그룹에 맞는 키를 선택합니다. 순서가 중요하지 않으면 고유 ID를 사용하거나 키를 두지 않는 선택도 가능합니다.
키가 한쪽으로 쏠리면 특정 연산자에 부하가 집중되어 처리량이 제한됩니다. 키 분포와 업무 순서 요구를 함께 고려합니다. Kafka에서 수집한다면 원천 Kafka 키에 대응하는 열을 사용하여 원천의 순서를 Foundry에서도 유지하도록 설계할 수 있습니다.
최종 출력의 보장은 전체 스트리밍 계보에서 가장 약한 순서 보장에 제한됩니다. 중간에 완전히 다른 키로 바꾸어도 새 키 관점에서 이미 순서가 뒤바뀐 레코드는 그대로 남습니다.