(번역: Dongwook Kim) Original Blog Post
데이터브릭스 델타 라이브 테이블(DLT)은 데이터 엔지니어가 작성하고 유지 관리해야 하는 코드의 양을 줄여 강력한 데이터 처리 파이프라인의 개발을 획기적으로 간소화합니다. 또한 데이터 유지 관리 및 인프라 운영의 필요성을 줄여주며, 사용자가 환경 간에 코드 및 파이프라인 구성을 원활 하게 추진할 수 있도록 지원합니다. 하지만 여전히 사람들은 파이프라인에서 코드 테스트를 수행해야 하며, 이를 효율적으로 수행할 수 있는 방법에 대한 질문을 자주 받습니다.
이 블로그 게시물에서는 여러 고객과 함께 일한 경험을 바탕으로 다음 항목을 다룹니다:
데브옵스 수행은 소프트웨어 개발 수명 주기(SDLC)를 단축하는 동시에 높은 품질을 제공하는 것을 목표로 합니다. 일반적으로 아래 단계를 포함합니다:
이러한 모든 사례는 델타 라이브 테이블 파이프라인에도 적용할 수 있습니다:
이를 위해 데이터브릭스 제품 포트폴리오의 다음과 같은 기능을 사용합니다:
DLT 파이프라인의 권장되는 개발 워크플로우 요약은 다음과 같습니다:
블로그 포스트의 나머지 부분에서는 일반적인 레이크하우스 아키텍처의 전형적인 브론즈/실버 레이어를 설명하기 위해 두 개의 테이블로만 구성된 매우 간단한 DLT 파이프라인을 예시로 사용하겠습니다. 배포 지침과 함께 전체 소스 코드는 깃허브에서 확인할 수 있습니다.
Note: DLT는 SQL과 Python API를 모두 제공하지만, 대부분의 블로그에서는 Python 구현에 초점을 맞추고 있지만 대부분의 모범 사례는 SQL 기반 파이프 라인에도 적용할 수 있습니다.
델타 라이브 테이블로 개발할 때 일반적인 개발 프로세스는 다음과 같습니다:
복잡한 파이프라인의 경우, 수십 개의 테이블/뷰가 있는 복잡한 파이프라인과 많은 라이브러리가 연결된 경우 파이프라인의 시작이 상대적으로 길어질 수 있기 때문에 이러한 개발 주기는 상당한 오버헤드를 초래할 수 있습니다. 사용자 입장에서는 샘플 데이터로 대화형 클러스터에서 개별 데이터 변환을 평가하고 테스트하여 매우 빠른 피드백을 얻는 것이 더 쉬울 것입니다.
개별 함수를 평가하고 테스트할 수 있게 하려면 올바른 코드 구조를 갖는 것이 매우 중요합니다. 일반적인 접근 방식은 모든 데이터 변환을 Spark 데이터프레임을 수신 및 반환하는 개별 함수로 정의하고, DLT 파이프라인 함수에서 이러한 함수를 호출하여 DLT 실행 그래프를 형성하는 것입니다. 이를 달성하는 가장 좋은 방법은 files in repos 기능을 사용해 Python 파 일을 일반 Python 모듈로 노출하여 데이터브릭스 노트북이나 다른 Python 코드로 가져올 수 있도록 하는 것입니다. DLT는 기본적으로 Python 파일을 Python 모듈로 가져올 수 있는 files in repos 기능을 지원합니다(files in repos을 사용할 때 Python의 sys.path에 두 개의 항목이 추가되는데, 하나는 Repo 최상위 디렉토리용이고 다른 하나는 호출하는 노트북의 현재 디렉터리용입니다). 이렇게 하면 Python 모듈로 가져올 Repo 루트 아래의 전용 폴더에 별도의 Python 파일로 코드 작성을 시작할 수 있습니다:
그리고 이 파이썬 패키지의 코드는 DLT 파이프라인 코드 내에서 사용할 수 있습니다:
이 특정 DLT 코드의 함수는 매우 간단합니다. 업스트림 테이블에서 데이터를 읽고 Python 모듈에 정의된 변환을 적용하는 것 뿐입니다. 이 접근 방식을 사용하면 DLT 코드를 더 간단하게 이해하고 로컬에서 또는 대 화형 클러스터에 연결된 별도의 노트북을 사용해 테스트하기 쉽게 만들 수 있습니다. 변환 로직을 별도의 Python 모듈로 분할하면 노트북에서 변환을 대화형으로 테스트하고, 이러한 변환에 대한 단위 테스트를 작성하고, 전체 파이프라인을 테스트할 수 있습니다(다음 섹션에서 테스트에 대해 설명합니다).
단위 및 통합 테스트가 포함된 데이터브릭스 리포지토리의 최종 구조는 다음과 같습니다:
이 코드 구조는 공통된 데이터 변환을 공유하는 여러 DLT 파이프라인으로 구성될 수 있는 대규모 프로젝트에서 특히 중요합니다.
위에서 언급했듯이 데이터 변환을 별도의 Python 모듈로 분리하면 개별 함수의 동작을 검사하는 단위 테스트를 더 쉽게 작성할 수 있습니다. 이러한 단위 테스트를 구현하는 방법을 선택할 수 있습니다:
데모 리포지토리에는 테스트의 로컬 실행과 노트북으로 테스트를 실행하는 이 두 가지 접근 방식에 대한 샘플 코드가 포함되어 있습니다. CI 파이프라인은 두 가지 접근 방식을 모두 보여줍니다.
이 두 가지 접근 방식은 모두 Python 코드에만 적용 가능하며, SQL을 사용하여 DLT 파이프라인을 구현하는 경우 다음 섹션에서 설명하는 접근 방식을 따라야 합니다.
단위 테스트를 통해 개별 변환이 정상적으로 작동하는지 확인할 수 있지만, 전체 파이프라인도 제대로 작동하는지 확인해야 합니다. 이는 보통 전체 파이프라인을 실행하는 통합 테스트로 구현되지만, 보통은 소량의 데이터에 대해 실행되며 실행 결과를 검증해야 합니다. 델타 라이브 테이블을 사용하면 통합 테스트를 구현하는 여러 가지 방법이 있습니다:
이 경우 여러 개의 Task로 구성된 데이터브릭스 워크플로우를 사용하여 통합 테스트를 구현할 수 있습니다(task values을 사용하여 task 간에 데이터 저장소 경로등의 데이터를 전달할 수도 있습니다). 일반적으로 이러한 워크플로우는 다음과 같은 작업으로 구성됩니다:
이 접근 방식의 가장 큰 단점은 설정 및 유효성 검사 작업을 위해 상당한 양의 보조 코드를 작성해야 하며, 설정 및 유효성 검사 작업을 실행하는 데 추가 컴퓨팅 자원이 필요하다는 것입니다.
결과가 제공된 기대치와 일치하지 않을 경우 실패 연산자를 사용해 데이터에 DLT 기대치를 적용하고 파이프라인을 실패시키는 추가 DLT 테이블로 DLT 파이프라인을 확장하여 DLT에 대한 통합 테스트를 구현할 수 있습니다. 기대치가 첨부된 DLT 테이블을 정의하는 추가 노트북을 포함하는 별도의 DLT 파이프라인을 생성하기만 하면 매우 쉽게 구현할 수 있습니다.
예를 들어 실버 테이블에 유형 열에 허용된 데이터만 포함되는지 확인하려면 다음 DLT 테이블을 추가하고 기대치를 첨부하면 됩니다:
통합 테스트를 위한 DLT 파이프라인의 결과는 다음과 같습니다(실행 그래프에 데이터가 유효한지 확인하는 두 개의 추가 테이블이 있습니다)
이는 DLT 파이프라인의 통합 테스트를 수행하는 데 권장되는 접근 방식입니다. 이 접근 방식을 사용하면 추가 컴퓨팅 리소스가 필요하지 않습니다. 모든 것이 동일한 DLT 파이프라인에서 실행되므로 클러스터 재사용이 가능하고, 모든 데이터가 보고 등에 사용할 수 있는 DLT 파이프라인의 이벤트 로그에 기록됩니다.
행의 고유성 확인, 결과에서 특정 행의 존재 여부 확인 등 고급 유효성 검사에 DLT 기대치를 사용하는 더 많은 예는 DLT 설명서를 참조하세요. 또한, 서로 다른 DLT 파이프라인 간에 재사용할 수 있도록 DLT 기대값 라이브러리를 공유 Python 모듈로 구축할 수도 있습니다.
DLT의 변경사항을 개발에서 운영환경으로 전환에 대해 이야기하기 위해서는 먼저 DLT의 여러 자산에 대해서 알아야합니다:
코드를 프로모션하는 가장 간단한 방법은 데이터브릭스 Repos를 사용하여 Git Repo 저장된 코드로 작업하는 것입니다. 코드 버전을 유지하는 것 외에도, Databricks Repos를 사용하면 Repos REST API 또는 Databricks CLI를 사용하여 코드 변경 사항을 다른 환경으로 쉽게 전파할 수 있습니다.
DLT는 처음부터 파이프라인 구성에서 코드를 분리하여 스키마, 데이터 위치 등을 지정할 수 있게 함으로써 단계 간 개발 운영간 프로모션이 더 쉬워지도록 합니다. 따라서 각 개발 운영환경 마다 동일한 코드를 사용하는 별도의 DLT 구성을 정의하는 동시에 데이터를 다른 위치에 저장하고 다른 클러스터 크기 등을 사용할 수 있습니다.
파이프라인 설정을 정의하기 위해 델타 라이브 테이블 REST API 또는 데이터브릭스 CLI의 파이프라인 명령을 사용할 수 있지만, 인스턴스 풀, 클러스터 정책 또는 기타 종속성을 사용해야 하는 경우에는 이 작업이 어려워집니다. 이 경우 보다 유연한 대안은 다른 리소스에 대한 종속성을 보다 쉽게 처리할 수 있는 Databricks Terraform Provider의 databricks_pipeline 리소스이며, Terraform 모듈을 사용하여 Terraform 코드를 모듈화하여 재사용할 수 있도록 만들 수 있습니다. 제공된 코드 저장소에는 여러 환경에 DLT 파 이프라인을 배포하기 위한 Terraform 코드의 예제가 포함되어 있습니다.
모든 개별 부분을 구현한 후에는 CI/CD 파이프라인을 구현하는 것이 비교적 쉽습니다. GitHub 리포지토리에는 Azure DevOps용 빌드 파이프라인이 포함되어 있습니다(다른 시스템도 지원 가능 - 일반적으로 파일 구조에 차이가 있음). 이 파이프라인은 특정 이벤트에 따라 서로 다른 테스트 집합을 실행하는 기능을 보여주는 두 단계로 구성되어 있습니다:
onRelease 단계에서 통합 테스트를 실행하는 것을 제외하면 두 단계의 구조는 동일하며, 다음 단계로 구성됩니다:
releases
브랜치의 경우 통합 테스트를 실행합니다.테스트 실행 결과는 Azure DevOps에 다시 보고되므로 추적가능 합니다.
releases 브랜치에 커밋이 완료되고 모든 테스트가 성공하면 release pipeline이 트리거되어 프로덕션 Databricks Repos를 업데이트할 수 있으므로 코드의 변경 사항이 다음번 DLT 파 이프라인 실행 시 반영됩니다.
이 블로그 게시물에 설명된 접근 방식을 여러분의 델타 라이브 테이블 파이프라인에 적용해 보세요! 제공된 데모 리포지토리에는 필요한 모든 코드와 함께 설정 지침 및 Azure DevOps에 모든 것을 배포하기 위한 Terraform 코드가 포함되어 있습니다.