자습서: JupyterLab에 Jupyter Notebook을 설정하여 ETL 스크립트 테스트 및 디버깅 - AWS Glue

자습서: JupyterLab에 Jupyter Notebook을 설정하여 ETL 스크립트 테스트 및 디버깅

이 튜토리얼에서는 로컬 시스템에서 실행 중인 JupyterLab의 Jupyter Notebook을 개발 엔드포인트에 연결합니다. 이렇게 하면 AWS Glue 추출, 변환, 로드(ETL) 스크립트를 배포하기에 앞서 대화식으로 이를 실행, 디버깅 및 테스트할 수 있습니다. 이 자습서에서는 Secure Shell(SSH) 전송을 사용하여 로컬 시스템을 AWS Glue 개발 엔드포인트에 연결합니다. 자세한 내용은 Wikipedia의 Port forwarding을 참조하세요.

이 튜토리얼에서는 자습서 사전 요구 사항에 개략적으로 소개된 단계를 이미 수행한 것으로 가정합니다.

1단계: JupyterLab과 Sparkmagic 설치

JupyterLab을 설치하려면 conda 또는 pip를 사용하면 됩니다. conda는 오픈 소스 패키지 관리 시스템 겸 환경 관리 시스템으로 Windows, macOS 및 Linux에서 실행됩니다. pip는 Python용 패키지 설치 프로그램입니다.

macOS에 설치하는 경우, Xcode가 설치되어 있어야 Sparkmagic을 설치할 수 있습니다.

  1. JupyterLab, Sparkmagic과 관련 확장 프로그램을 설치합니다.

    $ conda install -c conda-forge jupyterlab $ pip install sparkmagic $ jupyter nbextension enable --py --sys-prefix widgetsnbextension $ jupyter labextension install @jupyter-widgets/jupyterlab-manager
  2. Location에서 sparkmagic 디렉터리를 확인합니다.

    $ pip show sparkmagic | grep Location Location: /Users/username/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages
  3. 디렉터리를 Location에 대하여 반환된 것으로 변경하고, Scala와 PySpark의 커널을 설치합니다.

    $ cd /Users/username/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages $ jupyter-kernelspec install sparkmagic/kernels/sparkkernel $ jupyter-kernelspec install sparkmagic/kernels/pysparkkernel
  4. 샘플 config 파일을 다운로드합니다.

    $ curl -o ~/.sparkmagic/config.json https://raw.githubusercontent.com/jupyter-incubator/sparkmagic/master/sparkmagic/example_config.json

    이 구성 파일에서 driverMemoryexecutorCores와 같은 Spark 관련 파라미터를 구성할 수 있습니다.

2단계: JupyterLab 시작

JupyterLab을 시작하면 기본 웹 브라우저가 자동으로 열리고 URL http://localhost:8888/lab/workspaces/{workspace_name}이 표시됩니다.

$ jupyter lab

3단계: SSH 포트 전송을 시작하여 개발 엔드포인트에 연결

다음으로, SSH 로컬 포트 전송을 사용하여 로컬 포트(여기서는 8998)를 AWS Glue(169.254.76.1:8998)에 의해 정의된 원격 대상으로 전송합니다.

  1. SSH에 액세스를 부여하는 별도의 터미널 창을 엽니다. Microsoft Windows에서라면 Git for Windows에서 제공하는 BASH 셸을 사용해도 되고, 아니면 Cygwin을 설치해도 됩니다.

  2. 다음과 같이 수정된 다음 SSH 명령을 실행합니다.

    • private-key-file-path 대신 개발 엔드포인트를 생성하는 데 쓴 퍼블릭 키에 상응하는 프라이빗 키를 포함한 .pem 파일에 대한 경로를 사용합니다.

    • 8998 외의 다른 포트를 전송하는 경우, 8998 대신 로컬에서 실제로 사용 중인 포트 번호를 사용합니다. 주소 169.254.76.1:8998이 원격 포트이며 이는 사용자가 변경하는 것이 아닙니다.

    • dev-endpoint-public-dns를 개발 엔드포인트의 퍼블릭 DNS 주소로 바꿉니다. 이 주소를 찾으려면 AWS Glue 콘솔에서 개발 엔드포인트로 이동하여 이름을 선택하고 [엔드포인트 세부 정보(Endpoint details)] 페이지에 목록으로 기재된 [퍼블릭 주소(Public address)]를 복사합니다.

    ssh -i private-key-file-path -NTL 8998:169.254.76.1:8998 glue@dev-endpoint-public-dns

    다음과 같은 경고 메세지가 표시됩니다.

    The authenticity of host 'ec2-xx-xxx-xxx-xx.us-west-2.compute.amazonaws.com (xx.xxx.xxx.xx)' can't be established. ECDSA key fingerprint is SHA256:4e97875Brt+1wKzRko+JflSnp21X7aTP3BcFnHYLEts. Are you sure you want to continue connecting (yes/no)?

    yes를 입력하고 JupyterLab을 사용하는 동안 터미널 창을 열어둡니다.

  3. SSH 포트 전송이 개발 엔드포인트와 올바로 함께 작동하는지 확인합니다.

    $ curl localhost:8998/sessions {"from":0,"total":0,"sessions":[]}

4단계: Notebook Paragraph의 Simple Script Fragment 실행

이제 JupyterLab의 노트북이 개발 엔드포인트와 함께 작동하는 것이 정상입니다. 다음과 같은 스크립트 조각을 노트북에 입력하여 실행합니다.

  1. Spark가 실행 중인지 확인합니다. 다음 명령을 사용하면 Spark에 1을 계산하여 값을 인쇄하도록 지시합니다.

    spark.sql("select 1").show()
  2. AWS Glue Data Catalog 통합이 작동하는지 확인합니다. 다음 명령을 사용하면 테이블을 Data Catalog에 목록으로 나열합니다.

    spark.sql("show tables").show()
  3. AWS Glue 라이브러리를 사용하는 단순한 스크립트 조각이 작동하는지 확인합니다.

    다음 스크립트는 AWS Glue Data Catalog의 persons_json 테이블 메타데이터를 사용하여 샘플 데이터로부터 DynamicFrame을 생성합니다. 그런 다음 항목 수와 이 데이터 스키마를 출력합니다.

import sys from pyspark.context import SparkContext from awsglue.context import GlueContext # Create a Glue context glueContext = GlueContext(SparkContext.getOrCreate()) # Create a DynamicFrame using the 'persons_json' table persons_DyF = glueContext.create_dynamic_frame.from_catalog(database="legislators", table_name="persons_json") # Print out information about *this* data print("Count: ", persons_DyF.count()) persons_DyF.printSchema()

스크립트의 출력은 다음과 같습니다.

Count: 1961 root |-- family_name: string |-- name: string |-- links: array | |-- element: struct | | |-- note: string | | |-- url: string |-- gender: string |-- image: string |-- identifiers: array | |-- element: struct | | |-- scheme: string | | |-- identifier: string |-- other_names: array | |-- element: struct | | |-- note: string | | |-- name: string | | |-- lang: string |-- sort_name: string |-- images: array | |-- element: struct | | |-- url: string |-- given_name: string |-- birth_date: string |-- id: string |-- contact_details: array | |-- element: struct | | |-- type: string | | |-- value: string |-- death_date: string

문제 해결

  • JupyterLab 설치 중에 컴퓨터가 회사 프록시나 방화벽 뒤에 위치한 경우, 회사 IT 부서에서 관리하는 사용자 정의 보안 프로파일로 인해 HTTP 및 SSL 오류가 발생할 수 있습니다.

    다음은 conda가 자체 리포지토리에 연결할 수 없을 때 발생하는 일반적인 오류의 예시입니다.

    CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/main/win-64/current_repodata.json>

    이것은 회사에서 Python 및 JavaScript 커뮤니티에서 광범위하게 사용되는 리포지토리로의 연결을 차단할 수 있기 때문에 발생할 가능성이 있습니다. 자세한 내용은 JupyterLab 웹 사이트의 Installation Problems를 참조하세요.

  • 개발 엔드포인트에 연결을 시도할 때 [연결 거부됨(connection refused)] 오류가 발생하는 경우 날짜가 지난 개발 엔드포인트를 사용하고 있는 것일 수 있습니다. 새로운 개발 엔드포인트를 생성해보고 다시 연결하십시오.