데이터 엔지니어 기술 블로그

[Delta Lake] 데이터 레이크하우스: 프로토콜 본문

데이터 엔지니어링

[Delta Lake] 데이터 레이크하우스: 프로토콜

jun_yeong_park 2022. 3. 18. 20:28
반응형

1. 개요

1.1 Delta의 트랜잭션 구현 방법

다중 버전 동시성 제어(MVCC)

  • 테이블이 변경될 경우 즉시 교체하지 않고 데이터의 여러 복사본을 유지한다.

Reader는 트랜잭션 로그를 사용하여 처리할 데이터의 파일을 선택적으로 가져온다.

Writer는 새 데이터 파일이나 기존 파일의 업데이트된 복사본을 작성한다. 그 후 커밋하고 로그에 새 항목을 추가하여 테이블의 새로운 버전을 생성한다.

  • 이 로그에는 테이블에 대한 메타데이터 변경 사항과 함께 논리적으로 추가 및 제거할 데이터 파일이 기록된다.
  • vacuum 명령을 사용하여 추후에 지연 삭제할 수 있다.

2. Delta Table Specification

2.1 테이블 스냅샷

테이블에는 연속적으로 증가하는 정수를 사용한 로그가 있다. 특정 버전에서 테이블의 상태를 스냅샷이라고 한다.

  1. Version of the Delta log protocol: 델타 로그 프로토콜 버전
  2. Metadata: 테이블의 메타데이터
  3. Set of files: 테이블에 사용되는 파일들
  4. Set of tombstones: 삭제된 파일 표시 세트
  5. Set of applications-specific transactions: 커밋된 트랜잭션 세트

2.2 File Types

2.2.1 Data Files

데이터 파일은 실제 데이터가 있는 파일을 말한다.

/mytable/part-00000-3935a07c-416b-4344-ad97-2a38342ee2fc.c000.snappy.parquet

2.2.2 Delta Log Entries

델타 파일은 _delta_log 라는 디렉토리에 JSON으로 저장된다. 테이블에 발생한 모든 변경 사항의 로그를 가지고 있다.

./_delta_log/00000000000000000000.json

 

2.2.3 Checkpoint

체크포인트는 _delta_log 디렉토리에 저장되며 기본적으로 10회 커밋마다 체크포인트를 생성한다.

체크포인트에는 커밋메세지에 있던 액션들이 저장되며, 불필요한 액션들은 제거된다.

 

2.2.4 Last Checkpoint File

트랜잭션 로그는 많은 파일을 포함할 수 있기 때문에 리스팅하려면 많은 비용이 소모된다. last checkpoint file은 끝 부분에 대한 포인터를 제공한다.

_delta_log/_last_checkpoint

체크포인트 버전 ID가 여기에 사전순으로 정렬된다. 형태는 다음과 같다.

  • version: 이 파일이 만들어질 때의 테이블 버전
  • size: 체크포인트에 저장된 action의 수
  • parts: 조각 수

3. Actions

3.1 개요

actions는 state of the table을 수정하고 델타 파일체크포인트에 저장된다.

Metadata action은 테이블의 현재 메타데이터를 변경한다. 첫 번째 버전에는 metadata 작업이 반드시 포함되어있어야 하며 그 후에 메타데이터가 변경된다면 테이블의 현재 메타데이터를 완전히 덮어쓴다.

스키마

  • id
  • name
  • description
  • format(저장된 파일의 인코딩 정보)
    • provider
    • options
  • schemaString(테이블의 스키마)
  • partitionColumns(파티션 컬럼들)
  • createdTime
  • configuration

예제 1

{
  "metaData":{
    "id":"af23c9d7-fff1-4a5a-a2c8-55c59bd782aa",
    "format":{"provider":"parquet","options":{}},
    "schemaString":"...",
    "partitionColumns":[],
    "configuration":{
      "appendOnly": "true"
    }
  }
}

예제 2

{
   "metaData":{
      "id":"617705e4-11b5-4a6b-8347-a06830cbf358",
      "format":{
         "provider":"parquet",
         "options":{
            
         }
      },
      "schemaString":"{\\"type\\":\\"struct\\",\\"fields\\":[{\\"name\\":\\"id\\",\\"type\\":\\"long\\",\\"nullable\\":true,\\"metadata\\":{}}]}",
      "partitionColumns":[
         
      ],
      "configuration":{
         
      },
      "createdTime":1641720187780
   }
}

3.2 Add File & Remove File

3.2.1 Add 예제

{
  "add": {
    "path":"date=2017-12-10/part-000...c000.gz.parquet",
    "partitionValues":{"date":"2017-12-10"},
    "size":841454,
    "modificationTime":1512909768000,
    "dataChange":true
    "stats":"{\\"numRecords\\":1,\\"minValues\\":{\\"val..."
  }
}

3.2.2 Remove 예제

{
   "remove":{
      "path":"part-00012-72676cb8-317b-45ae-b39c-2a6d623780bf-c000.snappy.parquet",
      "deletionTimestamp":1641732216164,
      "dataChange":true,
      "extendedFileMetadata":true,
      "partitionValues":{
         
      },
      "size":478
   }
}

3.2.3 dataChange

실제로 데이터가 변경되었다면 True로 설정하고, 그 외에 데이터가 아닌 다른 값만 변경된 경우 False로 설정하여 추후에 특정 작업에서 속도를 개선할 수 있다.

3.3 프로토콜 버전

델타테이블을 읽고 쓰기 위한 버전이 업데이트가 되었을 때 과거의 버전으로 관리하던 테이블과 호환성 등을 확인하기 위해서는 버전 기록이 필요하다.

  • minReaderVersion: 읽기 위한 최소 호환 버전
  • minWriterVersion: 쓰기 위한 최소 호환 버전
{
  "protocol":{
    "minReaderVersion":1,
    "minWriterVersion":2
  }
}

3.4 CommitInfo

커밋에 대한 메타데이터는 아래와 같은 형식으로 저장된다.

{
  "commitInfo":{
    "timestamp":1515491537026,
    "userId":"100121",
    "userName":"michael@databricks.com",
    "operation":"INSERT",
    "operationParameters":{"mode":"Append","partitionBy":"[]"},
    "notebook":{
      "notebookId":"4443029",
      "notebookPath":"Users/michael@databricks.com/actions"},
      "clusterId":"1027-202406-pooh991"
  }
}
반응형
Comments