[Hands On] Glue를 이용한 데이터 전처리

S3로 수집한 데이터를 AWS Glue 서비스를 이용하여 손쉽게 분석에 사용될 데이터 형태로 전처리할 수 있습니다.  

01. IAM 역할 생성하기

먼저 Glue 서비스의 접근 권한이 부여된 IAM역할을 생성합니다.

1. IAM 콘솔에서 역할만들기 버튼을 클릭합니다.

2. 신뢰할 수 있는 엔터티 유형에서 AWS 서비스를 선택합니다.

3. 사용사례는 Glue를 선택합니다.

4. AWSGlueServiceRole 권한정책을 추가해줍니다.

5. 태그를 구성하여 역할을 생성합니다.

6. 테스트 중 AmazonS3FullAccess권한이 필요하여 추가해주었습니다.

02. ETL 대상 테이블 스키마 크롤링하기

Glue 크롤러를 사용하여 s3 에 적재된 로우 데이터 원본에 대한 테이블 스키마를 생성합니다.

Glue ETL 작업시 S3에 적재된 데이터를 바로 읽어서 진행도 가능하나,  데이터 카탈로그에 테이블 스키마를 생성하여 읽어내는 것이 ETL시 발생하는 예외사항 처리에 수월하게 느껴졌습니다. 

A. csv.gz 파일 데이터 크롤링
<S3 단일 경로 크롤링>

1. Glue콘솔 > 크롤러 메뉴에서 크롤러 추가 버튼을 클릭합니다.

2. 크롤러 이름, 태그를 설정합니다.

3. 소스유형은 데이터스토어, 모든 폴더를 대상으로 크롤링 옵션을 선택합니다.

4. 데이터스토어는 s3, 크롤링할 s3 경로를 입력합니다.

5. 위에서 생성한 IAM 역할 권한을 선택합니다.

6. 크롤러 일정은 온디맨드 실행으로 구성하였습니다. 크롤러를 통해 생성된 스키마에서 커스터마이징하여 수정하는 경우도 있기 때문에 온디맨드 실행을 선택하였습니다.

7. 데이터베이스를 생성하여 선택하고, 테이블명 접두사를 입력합니다.

8. 스키마 변경시에는 이전 데이터 가독성을 위해 새열만 추가 옵션으로 구성하였습니다.

9. 크롤러가 생성되어지면, 실행을 해봅니다.

10. 실행이 정상적으로 완료되면 추가된 테이블에 추가된 개수가 표시됩니다.

11. Glue 콘솔 > 데이터 카탈로그 > 데이터베이스 > 테이블메뉴에서 생성된 스키마를 확인해봅니다.  추가적으로 해당 스키마를 ETL시 사용할 경우,  Athena에서 생성된 스키마를 확인하여 정상적으로 조회되는 것을 확인하는것을 권장드립니다. 

<S3 다중 경로 크롤링>

1. S3동일 버킷 같은 경로에 위와 같은 dimensions 파일들이 적재됩니다. 각 하위 폴더 경로가 각각의 테이블 스키마로 크롤링되도록 설정해보겠습니다.

2. 크롤러 이름, 태그 등을 구성합니다.

3. dimensions 데이터 특성상 인용부호가 존재하여 크롤러의 분류자를 설정하여 인식되도록 추가해줬으나, 분류자로는 적용이 잘 안됩니다. 아래부분에 스키마 변경작업으로 인용부호가 잘 식별되어 컬럼화되도록 구성하는 방법 참고하시면 됩니다.

3. 크롤러 소스는 데이터스토어를 선택, 모든 폴더에 대해 크롤링을 수행하도록 선택합니다.

4. 데이터스토어는 s3, 크롤링 경로는 dimensions 버킷 경로를 선택합니다. company_id, product_id 데이터의 내용에는 인용부호로 감싸진 멀티라인 데이터들이 포함되어져 있어서, 다른 방식으로 스키마를 생성해야 하는 관계로 제외패턴에 추가하였습니다.

5. 다른 데이터 스토어는 추가하지 않습니다.

6. 위에서 생성해준 IAM역할을선택합니다.

7. 일정은 온디맨드로 필요할때만 실행할것입니다. 크롤러가 실행된 이후에 생성된 스키마들에 대해서 커스터마이징하게 옵션들을 설정할것이므로 다시 전체 스키마를 크롤링하여 추가 설정한 내용이 원복되지 않도록 주의합니다.

8. 데이터베이스를 선택하고, 테이블 접두사를 추가합니다.

9. dimensions 하위 경로별로 테이블들을 생성할 것이므로 S3 데이터 그룹화 동작에서 각 S3경로에 대해 단일 스키마생성 옵션을 비활성화 합니다.

10. 크롤러 실행하여 변경사항 발생시 새열만 추가 되도록 설정합니다.

11. 크롤러를 생성한 후 실행합니다.

12. 데이터카탈로그에서 테이블들을 확인해보면 dimensions 하위 경로들이 개별 테이블 스키마들로 생성되었습니다.

13. 실제 Athena에서 생성된 스키마들을 쿼리해보면 데이터의 몇몇 특징들때문에 정상적으로 컬럼화되어 조회되지 않습니다.

* 이제부터 세부 케이스별 조치 방법을 공유하겠습니다.

03. 테이블 스키마 변경 작업하기

Glue Crawler가 모든상황을 감지하여 완벽하게 테이블 스키마를 생성해주길 바랬지만 실제로는 그렇지 않았습니다. 몇가지 예외사항으로 인해 테이블 스키마를 조금씩 수정하는 작업이 필요합니다.

A. 인용 부호 식별하기

1. Athena에서 보이는 테이블 스키마의 unified_category_id컬럼의 데이터유형과 데이터 명세서에 있는 동일 컬럼 데이터유형이 서로 다릅니다.

2. Athena에서 unified_category_id 컬럼값을 살펴보면 name 컬럼의 인용부호 내의 공백때문에 잘못 식별되어 string 타입으로 인식되었습니다.

3. 데이터카탈로그 > 테이블 메뉴에서 해당 테이블의 상세정보의 테이블 편집버튼을 클릭합니다.

4. Serde 직렬화 라이브러리를 org.apache.hadoop.hive.serde2.OpenCSVSerde로 변경합니다.

5. Serde 파라미터에 escapeChar =\,  quoteChar = ” 값을 추가하여 적용합니다.

6. 스키마 편집메뉴에서 unified_category_id 컬럼의 데이터 형식을 bigint로 변경해봅니다.

7. 이제 잘 될거라고 생각했는데, Athena로 가서 다시 조회해 보니 이와 같은 에러메시지가 출력됩니다. bigint형식의 컬럼에 빈값이 존재하여 나타나는 현상입니다.

8. 키가 되는 컬럼을 제외하고 나머지 숫자형으로 되어있는 컬럼들을 string으로 변경하였습니다. Glue ETL 작업에서 parquet.snappy 방식으로 파일 포맷을 변경할때 형변환 문제를 적용할 것입니다.

9. 변경된 테이블 스키마로 Athena에서 다시 조회해 보면 정상 조회됩니다.

B. 컬럼명 인식오류 처리

1. Athena로 조회해 보면 컬럼명이 식별되지 못하고 값 리스트에 보여지는 현상이 나타납니다. 모든 컬럼의 값들이 문자열일때 컬럼명 식별을 크롤러가 자동으로 수행하지 못하는 거 같습니다.

2. 테이블 편집으로 가서 Serde 파라미터에 skip.header.line.count = 1 을 추가합니다.

3. 스키마 편집에서 컬럼명을 직접 수정합니다.

4. 다시 Athena에서 조회해보면 정상적으로 출력됩니다.

04. Glue Studio를 이용한 Glue ETL 작업 생성하기

API에서 연동된 로우 데이터들을 Athena에서 분석하기 위한 구조화된 데이터 처리가 필요합니다. Athena는 쿼리시 스캔되는 용량에 따라 비용이 발생함으로 효율적인 데이터 압축과 인코딩을 지원하는 파일포맷으로 데이터를 적재하는 것이 중요합니다.

.csv.gz 파일을 .parquet.snappy파일로 변경하는 Glue ETL 작업을 생성합니다.

Glue Studio 기능을 활용하여 Glue ETL작업을 손쉽게 구성할 수 있습니다.

Apache Parquet와 같은 컬럼 형식 스토리지는 CSV와 같은 행 기반 파일에 비해 효율성을 개선하기 위해 고안한 것입니다. 컬럼 형식 스토리지는 쿼리할 때 개연성이 없는 데이터는 아주 신속하게 건너뛸 수 있습니다. 따라서 집계 쿼리를 수행할 때 행 중심 데이터베이스에 비해 시간이 적게 걸립니다. 이런 방식의 스토리지를 이용하면 하드웨어를 절약할 수 있고 데이터 액세스를 위한 레이턴시를 최소화할 수 있습니다.

구글에서 자체 개발한 압축 라이브러리이며, 최고의 압축률 보다는 적정 수준의 압축률을 제공하면서 빠르게 압축하고 해제하는 것을 목표로 합니다.

A. S3 버킷 생성하기
Bulk데이터 분석용 S3버킷 생성
Not Bulk데이터 분석용 S3버킷 생성

1. parquet 파일 적재를 위한 s3버킷을 생성합니다. Bulk 데이터, Not Bulk 데이터 적재를 위한 2개의 버킷을 생성합니다.

2. API별 데이터 적재를 위한 하위 폴더들을 생성합니다.

3. Glue Studio 작업으로 생성될 script 들을 저장해 놓을 버킷을 별도로 생성하였습니다. 결국 Glue ETL 잡은 이렇게 생성된 script들을 실행하는 것입니다. 잘 보관해두어야 합니다.

B. Json 반정형데이터 변환하기
<Json 구조화된 어레이 각각의 요소들을 컬럼화하기>

1. 위와 같은 Json 형태의 데이터가 있습니다. product라는 리스트로 된 어레이들로 구성되어져 있는 키가 있습니다. product내의 어레이들 각각에서 키값들을 컬럼으로 저장해야 Athena에서 쿼리하기 편리해 보입니다.

2. Glue Studio 콘솔에서 Jobs메뉴의 작업 유형(Visual), 소스(S3), 타켓(S3)을 선택 후 create 버튼을 클릭합니다.

2. 타이틀을 입력합니다.

3. Visual창에서 Data source를 선택하고 소스데이터가 위치한 s3 URL을 입력합니다.

4. Data format은 JSON, JsonPath는 $.product라고 입력합니다. 이 옵션처리로 위의 Json 구조체에서 product 패스 하위 정보들이 컬럼으로 구성되게 됩니다.

5. Multiline을 활성화합니다.

6. output 스키마 탭을 선택하여 식별된 컬럼들을 확인합니다.

7. Visual창에서 Transform-ApplyMapping을 클릭하여 변환시 컬럼명을 변경해 줍니다.  iphone6+ 을 iphone6_plus로 변경해주었습니다. Athena에서는 컬럼명에 + 특수문자를 지원하지 않습니다.

8. Visual창에서 Data  target을 선택하고 Format은 parquet, 압축유형은 Snappy를 선택합니다.

9. S3 타켓위치는 위에서 생성해준 버킷내 폴더 위치를 선택합니다.

10. Json 중첩 어레이가 포함된 데이터구조체는 데이터 카탈로그를 변경할 수 없다고 안내가 되어있습니다. 스키마 작업은 별도로 진행해야합니다.

11. Job Details에서 Description을 입력하고 IAM Role을 위에서 생성한 역할을 선택합니다.

12. worker 수를 자동확장을 활성화합니다.

13. Job bookmark를 활성화 합니다.

14. retry 횟수는 0으로 변경하였습니다.

15. Glue Script 파일이 생성되어 저장되는 S3 경로를 별도로 생성해주어 설정해주었습니다. Script 보관이 유지보수를 위해 중요합니다. 경로 지정시 Browse S3버튼 눌러서 선택하고 나면 경로 마지막에 “/”가 붙어있지 않습니다. 반드시 붙여주시기 바랍니다.  (안붙이면 알수없는 오류가 발생할 수 있습니다.)

16. 태그를 구성합니다.

17. Job 설정을 저장하고 Run 버튼을 클릭하여 실행합니다.

18. Job 실행상태를 확인가능합니다. 정상 실행되었습니다.

19. S3에 적재된 버킷을 확인하여 .parquet.snappy 형태로 ETL 되었음을 확인가능합니다.

20. 위에 ETL되어 .parquet.snappy로 적재된 데이터를 Athena에서 분석시 접근할 테이블을 생성하기 위한 크롤러를 추가합니다.

21. 크롤러 이름을 입력하고 태그를 구성합니다.

22. 크롤러의 소스타입을 데이터스토어로 선택, 크롤링때마다 버킷 전체를 크롤링하도록 선택합니다.

23. 크롤링할 파일의 s3 적재경로를 선택합니다.

24. IAM역할을 선택합니다.

25. 크롤러의 일정은 온디맨드를 선택합니다.

 

26. Athena의 분석시에 접근할 데이터베이스를 별도로 생성해주고, 크롤링시 새로 생성한 데이터베이스의 테이블스키마를 생성하도록 선택합니다.

27. 나머지 크롤러 설정부분은 앞에서 언급한 사항들을 참고로 하여 생성을 완료하고 실행시켜줍니다.

28. 생성된 스키마를 통해 Athena에서 쿼리로 데이터를 확인가능합니다.

C.csv.gz 데이터 변환하기
<partition키를 가진 스키마로 변환하기>

Athena에서 분석을 할때 데이터를 분할하면 각 쿼리가 스캔하는 데이터의 양을 제한하여 성능을 향상시키고 비용을 절감할 수 있습니다. 어떤 키를 기준으로도 데이터를 분할할 수 있습니다. 다만 데이터의 의미를 파악하고 분석조건에 자주 언급될 키를 기준으로 분할을 해야합니다.

[AWS]데이터 AI 플랫폼 API연동 및 분석 에서 Bulk API로 연동되는 데이터는 수집일시의 컬럼이 존재하는 데이터, 없는 데이터 종류로 구분되었습니다. 

이 중 수집일시의 컬럼이 존재하는 데이터에 대해서만 파티셔닝을 적용하였습니다.

1. Visual 탭에서 Data Source를 미리 생성해 놓은 raw 데이터위치를 가리키는 데이터카탈로그에 등록된 테이블을 선택합니다.

2. Transform을 선택하면 컬럼 매핑정보가 출력됩니다. date 컬럼이 long 타입으로 되어있는 것을 timestamp 유형으로 변경합니다. 실제로 timestamp 값입니다.

3. Visual 탭에서 Data target을 선택하여 parquet 포맷, snappy 압축방식을 선택합니다. 

4. ETL 되서 업로드될 S3 Target 경로를 선택합니다. 해당 경로는 미리 생성해 놓습니다.

5. Create a table in the Data Catalog and on subsequent runs, keep existing schema and add new partitions 옵션을 선택하고 데이터 카탈로그에 생성될 테이블명 또한 입력해줍니다.

6. 파티션 정보로 date 컬럼을 선택합니다. 가이드로 제공되는 테이블 명세를 보면 date컬럼이 수집되는 일자 정보로 되어있습니다. 해당 가이드가 변경될 경우 파티션 키는 재 설계 될 필요가 있습니다.

7. 이외 Glue ETL 설정작업은 위에 다른 Job들을 설정할때의 정보와 동일하게 설정하였습니다.

8. 설정내용을 저장 후 Run버튼을 실행하여 Success되었습니다.

9. Athena로 가서 조회해 보면 입력했던 테이블명으로 조회가능한 것을 확인합니다. date컬럼으로 파티셔닝 되어있음을 확인가능합니다.

10. Glue Studio 의 상단의 Schedules 탭을 클릭하면 Schedule Job 설정화면에 진입됩니다.

11. API 연동배치를 UTC 0시 5분에 실행되게 해놓은 관계로 ETL은 1시 0로 설정했습니다.

12. 스케줄링이 등록된 정보입니다.

13. 파티셔닝 된 테이블이 S3에 적재된 구조입니다.

<Glue Studio 기반 스크립트 손쉽게 변환하기>

Glue Studio는 시각적으로 ETL 워크플로우를 쉽게 구성해서 스크립트를 생성해줍니다. 데이터의 특징에 따라서는 이렇게 만들어진 스크립트만으로는 처리하기 부족하고, 직접 작성해야하는 경우도 있습니다.

이번 작업시 dimensions 데이터는 코드성 데이터로 일별 Bulk Data 연동시에 그 시점의 코드 데이터도 매일 연동되는 특성을 가집니다. dimensions데이터는 현시점의 데이터가 필요한 관계로, 테이블스키마가 가리키는 S3 위치를 매일 ETL시 업데이트 해주고 싶었습니다.  

Glue Studio로 스크립트를 생성 후 그렇게 생성된 스크립트를 변환해서 ETL 작업을 생성하였습니다.

1. Glue Studio Visual 탭에서 Data Source를 선택합니다.

2. ETL 소스인 Data Catalog Table의 Database와 Table을  선택합니다.

3. Visual 탭에서 Transform – ApplyMapping을 선택하고,  위에 정리한 03. 테이블 스키마 변경 작업하기에서 널데이터로 인한 형변환시 발생하는 오류로 인해 String으로 설정했던 컬럼들을 테이블 가이드에서 안내한 long 타입으로 변경되도록 설정합니다.

4. Transform 작업을 추가로 구성할 예정이므로 Visual에 디폴트로 구성되어있는 Data Target을 Remove합니다.

5. Visual 탭의 상단 툴바에 Transform 드롭다운 메뉴중 Drop Duplications 기능을 선택합니다.

6. 전체 행에 대한 Distinct 옵션을 선택합니다. 

이 설정을 추가 해준 이유는   ETL 초기 시작시 또는 장애발생으로 ETL이 몇일간 중단될 경우  ETL되지 않은  로우 데이터가 많이 쌓이게 되는 경우가 발생할 수 있습니다.  이때  ETL을 시작하면 코드성 데이터가 중복으로 분석데이터로 적재될 가능성이 존재하여 Distinct 기능을 추가하였습니다.

정상적으로 ETL이 일별로 수행되게 되면 Glue ETL의 bookmark 기능으로 인해 당일 수집된 데이터만 ETL 되도록 동작할것입니다. 이때 중복을 관리하고 당일 수집된 데이터만 코드데이터로 읽힐 수 있도록 S3 적재구조를 구성하였고 뒷부분 스크립트 수정 부분에서 설명하겠습니다.

AWS Glue는 작업 실행의 상태 정보를 유지하여 이전에 ETL 작업을 실행할 때 이미 처리된 데이터를 추적합니다. 이와 같은 지속 상태 정보를 작업 북마크라고 합니다. AWS Glue는 작업 북마크로 상태 정보를 유지하고 이전 데이터의 재처리를 방지합니다. 

7.  Visual 탭의 상단툴바에서 Target드롭다운 메뉴를 선택하고 Amazon S3를 선택합니다.

8. Visual 탭에서 Data Target의 S3를 선택하고 Format은 parquet, 압축유형은 snappy, S3 Target 위치, ETL된 데이터의 DataCatalog 테이블 스키마 작성 옵션등을 입력합니다. S3 Target위치는 Glue Studio 작업 저장시 생성되는 스크립트에서 동적으로 변경되도록 수정할 예정이므로 임시로 선택합니다.

9. Visual 탭옆에 Script탭을 선택하여 Edit Script버튼을 누르면 편집모드가 됩니다.

10. 스크립트에서 필요한 내용으로 변경합니다.

변경 및 추가한 내용은 두가지입니다.

  • ETL 완료된 테이블 스키마 크롤링시 S3 위치가 업데이트 되지 않는 현상이 있어서, 이미 생성된 스키마 삭제 후 새로이 생성되도록 하였습니다.
  • ETL 되는 데이터의 S3적재 경로는 일별 폴더로 적재되도록 동적으로 S3경로를 생성해주었습니다.
11. Job Details 정보 및 스케줄러 정보등을 설정합니다.

12. Athena에서 생성된 테이블이 정상 조회됨을 확인합니다.

<인용부호가 있는 멀티라인 데이터 처리하기>

앞에서 인용부호(쌍따옴표 “)가 있는 테이블은 테이블 스키마 옵션등을 설정해서 처리하였습니다.

이때 인용부호 내에 멀티라인 데이터가 존재하는 데이터는 단순히 스키마 옵션으로 읽혀지지 않았고, Glue ETL 스크립트에서 처리가능한 옵션을 발견하였습니다. 현재 문제가 발생한 데이터 연동에는 적용하였으며, 추후 동일 문제 발생시 해당 내용 참고하시기 바랍니다.

이 작업 또한 Glue Studio를 이용해서 워크플로우를 생성하여 간단한 스크립트 기반 코드를 자동으로 생성해 놓고 필요한 부분을 수정하는 방식으로 진행하였습니다.

1. Visual 탭에서 Data Source를 S3를 선택합니다.

2. source의 S3위치는 API연동된 raw데이터가 적재된어있는 폴더위치를 선택합니다.

3. Quote 캐릭터를 Double Quote(“)를 선택하고 Header 포함, multiline 옵션등을 선택합니다. 

4. 위에서와 동일하게 Drop Duplicates  액션을 추가하였으며, Target S3 정보를 설정하였습니다.

5. 동적으로 생성된 스크립트에서 필요한 부분들을 수정합니다.

  • ETL 완료된 테이블 스키마 크롤링시 S3 위치가 업데이트 되지 않는 현상이 있어서, 이미 생성된 스키마 삭제 후 새로이 생성되도록 하였습니다.
  • ETL 되는 데이터의 S3적재 경로는 일별 폴더로 적재되도록 동적으로 S3경로를 생성해주었습니다.
  •  multiline 옵션, quateChar 옵션등이 생성되어있는 것을 확인하고 혹시 없다면 적절히 편집해줍니다.
  • S3에서 읽어낸 컬럼들의 데이터 유형은 String으로 지정해서 읽고 변형시 데이터 유형을 지정하여 변형해야 모든 컬럼들이 정상적으로 읽혀지는 것으로 확인되었습니다.

6. Job Details 정보 및 스케줄러 정보등을 설정합니다.

* Glue Studio 와 같이 편리하게 시각적 도구로 ETL 스크립트를 생성해주는 서비스가 존재하나, 코드 작업을 배제할 수는 없을 거 같습니다. ETL 하는 데이터의 특성을 잘 이해하고, 필요에 따라 Spark 문법, AWS SDK 라이브러리 등의 활용도 필요합니다.

위에 구성한 코드성 데이터의 ETL 작업은 API 수집 당일 배치가 정상적으로 수행된다는 전제 하에 정상동작합니다. API 수집 당일 연동이 실패할 경우(테스트 과정 중 데이터 AI 플랫폼에서 Bulk 파일이 수신 안되는 날이 존재하네요. ㅜ) 코드성 테이블의 처리도 실패되어 Athena에서 조회되지 않는 현상이 발생가능합니다.  추후 각 단계별 실패시의 워크플로우 처리과정을 보완할 필요가 있으며, poc단계에서는 수동 처리할 수 있는 Tip을 알려드립니다.