본문 바로가기
WIKI 기술 지식 베이스

데이터 익스포트

원문 보기 위키 갱신

데이터 익스포트 (Exporting Data)

익스포트 작업은 지정한 lakeFS 커밋의 모든 데이터를 지정된 오브젝트 스토어 위치로 복사해요.

예를 들어 lakefs://example/main의 내용을 s3://company-bucket/example/latest로 내보낼 수 있어요. lakeFS를 전혀 모르는 클라이언트도 그 base URL로 main의 최신 파일에 접근할 수 있죠. lakeFS를 아는 클라이언트는 계속해서 lakeFS S3 엔드포인트로 s3://example/main의 저장소 파일과 다른 버전들, 커밋되지 않은 버전에 접근하면 돼요.

출처: 문서

본문

가능한 사용 사례:

  • 데이터의 외부 소비자가 여러분의 lakeFS 설치에 접근할 수 없어요.

  • 조직의 일부 데이터 파이프라인이 아직 lakeFS로 완전히 이전되지 않았어요.

  • lakeFS를 나란히(side-by-side) 설치해서 먼저 실험해 보고 싶어요.

  • 다른 리전에 데이터 레이크 복사본을 만들고 싶어요(읽기 가격을 고려하세요).

Spark로 데이터 익스포트하기

spark-submit 사용

export main을 세 가지 모드로 쓸 수 있어요:

  • example-repo 저장소의 example-branch 브랜치에서 모든 객체를 S3 위치 s3://example-bucket/prefix/로 내보내요:
.... example-repo s3://example-bucket/prefix/ --branch=example-branch
  • example-repo 저장소의 커밋 c805e49bafb841a0875f49cd555b397340bbd9b8에서 모든 객체를 S3 위치 s3://example-bucket/prefix/로 내보내요:
.... example-repo s3://example-bucket/prefix/ --commit_id=c805e49bafb841a0875f49cd555b397340bbd9b8
  • example-repo 저장소에서 브랜치 example-branch와 커밋 c805e49bafb841a0875f49cd555b397340bbd9b8 사이의 diff만 S3 위치 s3://example-bucket/prefix/로 내보내요:
.... example-repo s3://example-bucket/prefix/ --branch=example-branch --prev_commit_id=c805e49bafb841a0875f49cd555b397340bbd9b8

완성된 spark-submit 명령은 다음과 같아요:

lakeFS Enterprise

spark-submit --conf spark.hadoop.lakefs.api.url=https://<LAKEFS_ENDPOINT>/api/v1 \
    --conf spark.hadoop.lakefs.api.access_key=<LAKEFS_ACCESS_KEY_ID> \
    --conf spark.hadoop.lakefs.api.secret_key=<LAKEFS_SECRET_ACCESS_KEY> \
    --packages io.lakefs:lakefs-spark-client-enterprise_2.12:0.25.0 \
    --class io.treeverse.clients.Main export-app example-repo s3://example-bucket/prefix \
    --branch=example-branch

lakeFS Community

spark-submit --conf spark.hadoop.lakefs.api.url=https://<LAKEFS_ENDPOINT>/api/v1 \
    --conf spark.hadoop.lakefs.api.access_key=<LAKEFS_ACCESS_KEY_ID> \
    --conf spark.hadoop.lakefs.api.secret_key=<LAKEFS_SECRET_ACCESS_KEY> \
    --packages io.lakefs:lakefs-spark-client_2.12:0.22.0 \
    --class io.treeverse.clients.Main export-app example-repo s3://example-bucket/prefix \
    --branch=example-branch

정보

이 명령은 Spark 클러스터가 s3://example-bucket/prefix에 쓸 권한이 있다고 가정해요. 그렇지 않다면 적절한 자격 증명으로 spark.hadoop.fs.s3a.access.key와 spark.hadoop.fs.s3a.secret.key를 추가하세요.

네트워킹

Spark 익스포트는 lakeFS 서버와 통신해요. 매우 큰 저장소에서는 읽기 타임아웃을 늘려야 할 수 있어요. Spark 잡에서 lakeFS로의 통신 중 타임아웃 오류가 발생하면 다음 타임아웃을 늘려 보세요:

  • -c spark.hadoop.lakefs.api.read.timeout_seconds=TIMEOUT_IN_SECONDS(기본값 10)를 추가해 lakeFS가 요청에 응답할 시간을 더 주세요.

  • -c spark.hadoop.lakefs.api.connection.timeout_seconds=TIMEOUT_IN_SECONDS(기본값 10)를 추가해 lakeFS가 연결을 받아들이기를 기다리는 시간을 늘리세요.

커스텀 코드 사용 (Notebook/Spark)

이전 페이지의 안내대로 엔드포인트와 자격 증명으로 lakeFS Spark metadata client를 설정해요.

클라이언트는 세 가지 익스포트 옵션을 가진 Exporter 객체를 노출해요:

지정한 브랜치의 HEAD에 있는 모든 객체를 내보내요. 해당 브랜치에 추가됐지만 커밋되지 않은 파일은 포함하지 않아요.

Scala

exportAllFromBranch(branch: String)

커밋의 모든 객체를 내보내요:

Scala

exportAllFromCommit(commitID: String)

커밋과 브랜치 HEAD 사이의 diff만 내보내요. 이전 커밋 이후에 바뀐 파일만 바꾸기 때문에 브랜치의 지속적(continuous) 익스포트에 이상적이에요.

Scala

exportFrom(branch: String, prevCommitID: String)

성공/실패 표시

Spark 익스포트 작업이 끝나면 대상 루트에 상태 파일이 하나 추가돼요. 모든 파일이 성공적으로 익스포트됐다면 파일 경로는 EXPORT_<commitID>_<ISO-8601-time-UTC>_SUCCESS 형태예요. 실패라면 EXPORT_<commitID>_<ISO-8601-time-UTC>_FAILURE 형태이고, 파일 안에 실패한 파일 작업의 로그가 들어가요.

익스포트 라운드 (Spark success files)

어떤 파일은 다른 파일보다 먼저 익스포트되어야 해요. 예를 들어 같은 접두사 아래의 다른 파일보다 Spark _SUCCESS 파일이 먼저 익스포트되면 잘못된 신호가 될 수 있죠.

익스포트 작업 하나 안에 여러 라운드(round) 가 있을 수 있어요. 한 라운드가 실패하면 다음 라운드 파일들의 익스포트가 중단돼요.

기본적으로 lakeFS는 SparkFilter를 사용하고 각 익스포트에 2개의 라운드를 둬요. 첫 라운드는 Spark가 아닌 _SUCCESS 파일을 내보내고, 두 번째 라운드는 Spark의 _SUCCESS 파일 전부를 내보내요. Exporter에 커스텀 filter를 전달해 기본 동작을 바꿀 수 있어요.

예시

먼저 Exporter 인스턴스를 설정해요:

Scala

import io.treeverse.clients.{ApiClient, Exporter}
import org.apache.spark.sql.SparkSession

val endpoint = "http://<LAKEFS_ENDPOINT>/api/v1"
val accessKey = "<LAKEFS_ACCESS_KEY_ID>"
val secretKey = "<LAKEFS_SECRET_ACCESS_KEY>"

val repo = "example-repo"

val spark = SparkSession.builder().appName("I can export").master("local").getOrCreate()
val sc = spark.sparkContext
sc.hadoopConfiguration.set("lakefs.api.url", endpoint)
sc.hadoopConfiguration.set("lakefs.api.access_key", accessKey)
sc.hadoopConfiguration.set("lakefs.api.secret_key", secretKey)

// Add any required spark context configuration for s3
val rootLocation = "s3://company-bucket/example/latest"

val apiClient = new ApiClient(endpoint, accessKey, secretKey)
val exporter = new Exporter(spark, apiClient, repo, rootLocation)

이제 main 브랜치의 모든 객체를 s3://company-bucket/example/latest로 내보낼 수 있어요:

Scala

val branch = "main"
exporter.exportAllFromBranch(branch)

커밋 f3c450d8cd0e84ac67e7bc1c5dcde9bef82d8ba7에 이전 익스포트가 성공했다고 가정하면, main 브랜치와 그 커밋 사이의 차이만 익스포트할 수도 있어요:

Scala

val branch = "main"
val commit = "f3c450d8cd0e84ac67e7bc1c5dcde9bef82d8ba7"
exporter.exportFrom(branch, commit)

Docker로 데이터 익스포트하기

도구 세트에 Spark가 없다면 이 옵션을 권해요. 여러 머신에 걸친 분산은 지원하지 않기 때문에 성능이 더 낮을 수 있어요. 이 방법으로는 Spark 익스포트와 비슷한 방식의 익스포트 옵션을 써서 lakeFS에서 S3로 데이터를 내보낼 수 있어요:

  • example-repo 저장소의 example-branch 브랜치에서 모든 객체를 S3 위치 s3://destination-bucket/prefix/로 내보내요:
.... example-repo s3://destination-bucket/prefix/ --branch="example-branch"
  • example-repo 저장소의 커밋 c805e49bafb841a0875f49cd555b397340bbd9b8에서 모든 객체를 S3 위치 s3://destination-bucket/prefix/로 내보내요:
.... example-repo s3://destination-bucket/prefix/ --commit_id=c805e49bafb841a0875f49cd555b397340bbd9b8
  • example-repo 저장소에서 브랜치 example-branch와 커밋 c805e49bafb841a0875f49cd555b397340bbd9b8 사이의 diff만 S3 위치 s3://destination-bucket/prefix/로 내보내요:
.... example-repo s3://destination-bucket/prefix/ --branch="example-branch" --prev_commit_id=c805e49bafb841a0875f49cd555b397340bbd9b8

관련 환경 변수를 추가해야 해요. 완성된 docker run 명령은 다음과 같아요:

docker run \
    -e LAKEFS_ACCESS_KEY_ID=XXX -e LAKEFS_SECRET_ACCESS_KEY=YYY \
    -e LAKEFS_ENDPOINT=https://<LAKEFS_ENDPOINT>/ \
    -e AWS_ACCESS_KEY_ID=XXX -e AWS_SECRET_ACCESS_KEY=YYY \
    treeverse/lakefs-rclone-export:latest \
        example-repo \
        s3://destination-bucket/prefix/ \
        --branch="example-branch"

참고

이 기능은 rclone, 그중에서도 rclone sync를 사용해요. 대상 경로를 바꿀 수 있으므로, s3 대상 위치는 lakeFS 익스포트 전용으로 지정해야 해요.

더 알아보기 (Learn more)

공식 문서: lakeFS Export 가이드