Amazon QuickSight

 

QuickSight workflow


참고: https://catalog.workshops.aws/quicksight/en-US

데이터 세트: SaaS-Sales.csv

위의 데이터 세트로 진행한다.

 

QuickSight 설정

그냥 계정 설정하면 된다... (일단은 standard로 지정)

그 다음 데이터 세트를 생성한다.

시각화 클릭
분석 이름 변경 가능

QuickSight 시각화

목표는 월별 매출 시각화 이다.

위와 같이 선택해주고 

Order Date의 집계를 Month로 설정해준다.

위와 같은 결과를 확인할 수 있다.

근데 여기서 문제는 내가 standard로 진행해서 추가적인 작업이 힘들다... 왜 Enterprise로 하라고 했는지 알 것 같기도....?

이런 식으로 데이터를 시각화를 하는 것!

 

 

❗ 뭔가 엔터프라이즈는 사용하기에 무서워서... 테스트 용이니까 standard로 진행했닿ㅎㅎ ❗

'Cloud > AWS' 카테고리의 다른 글

[AWS] Serverless Service - DynamoDB 편(1)  (0) 2022.12.02
[AWS] AppStream 2.0  (0) 2022.11.26
[AWS] Amazon Athena 사용법 -3  (0) 2022.11.20
[AWS] Amazon Athena 사용법 -2 + Glue(Crawler) 활용  (1) 2022.11.19
[AWS] Amazon Athena 사용법 -1  (1) 2022.11.19

Athena 사용법: https://realyun99.tistory.com/147

 

[AWS] Amazon Athena 사용법

먼저 Athena가 뭐하는 친군지 살펴보자. Amazon Athena 표준 SQL을 사용해 S3에 저장된 데이터를 간편하게 분석할 수 있는 대화식 쿼리 서버리스 서비스 그냥 단순히 S3에 저장된 데이터를 가리키고 스

realyun99.tistory.com

Athena+Glue(Crawler) 활용: https://realyun99.tistory.com/148

 

[AWS] Amazon Athena + Glue(Crawler) 활용

Athena 사용법: https://realyun99.tistory.com/147 [AWS] Amazon Athena 사용법 먼저 Athena가 뭐하는 친군지 살펴보자. Amazon Athena 표준 SQL을 사용해 S3에 저장된 데이터를 간편하게 분석할 수 있는 대화식..

realyun99.tistory.com

저번 포스팅들에 이어서 계속 진행해볼 것...


  • Athena CTAS를 사용한 ETL

대부분의 경우 데이터 레이크 또는 테이블로 들어오는 raw data는 csv 또는 텍스트 형식이다.

이런 형식은 Athena, 기타 엔진으로 쿼리하는 데 최적이 아니다. 데이터를 parquet과 같은 포맷으로 변환하는 것이 좋다.

CTAS(Create Table As Select) 쿼리를 사용해 테이블을 tsv 형식에서 parquet 포맷으로 변환하고 압축 및 분할을 통해 저장할 것..

 

저장된 쿼리에서 Athena_ctas_reviews를 실행해보자

(s3 버킷 이름을 잘 설정 해주자!)

다음 쿼리를 실행하면 다음과 같이 결과를 볼 수 있다.

명령들을 좀 살펴보자!

CREATE TABLE amazon_reviews_by_marketplace
WITH ( format='PARQUET', parquet_compression = 'SNAPPY', partitioned_by = ARRAY['marketplace', 'year'], 
external_location =   's3://<<Bucket-name>>/athena-ctas-insert-into/') AS
SELECT customer_id,
        review_id,
        product_id,
        product_parent,
        product_title,
        product_category,
        star_rating,
        helpful_votes,
        total_votes,
        verified_purchase,
        review_headline,
        review_body,
        review_date,
        marketplace,
        year(review_date) AS year
FROM amazon_reviews_tsv
WHERE "$path" LIKE '%tsv.gz';

/* Let's try to find the products and their corresponding category by number of reviews and avg star rating for US marketplace in year 2015 */

SELECT product_id,
        product_category,
        product_title,
        count(*) AS num_reviews,
        avg(star_rating) AS avg_stars
FROM amazon_reviews_by_marketplace
WHERE marketplace='US'
AND year=2015
GROUP BY  1, 2, 3
ORDER BY  4 DESC limit 10;

parquet_compression = 'SNAPPY' 같은 경우는 압축 방식을 정하는 것..

https://docs.aws.amazon.com/ko_kr/athena/latest/ug/compression-formats.html

 

Like 구문: SELECT * FROM [table name] WHERE [column] LIKE [condition];

부분적으로 일치하는 컬럼을 찾을 때 사용

 

  • Athena Workgroups

Workgroup: 사용자, 팀, 애플리케이션 또는 워크로드를 분리하고 각 쿼리 또는 전체 workgroup이 처리할 수 있는 데이터 양에 대한 제한을 설정하고 비용을 추적한다.

"Workgroup이 리소스 역할을 하기 때문에 리소스 수준 ID 기반 정책을 사용해 특정 workgroup에 대한 액세스 제어 가능!"

 

저번 포스팅의 테이블 생성 실습에서 primary 작업 그룹에 대한 CloudWatch 메트릭을 활성화했다.

CloudWatch 지표를 확인해보자(작업 그룹 → primary → 지표)

 

데이터 사용 제한을 설정해보자.

workgroupA를 클릭한 뒤 편집에 들어가 해당 데이터를 제한하자.

CloudFormation을 열고 스택 출력에 들어가 ConsolePassword 링크 클릭(AWS Secrets Manager로 이동)

해당 암호 값 검색을 통해 비밀번호를 확인하자.

 

시크릿 탭을 열어

IAM user name: userA

Password: 복사한 비밀번호 로 로그인하자.

 

Athena 콘솔을 열고 쿼리 결과 위치에 primary 위치를 입력한 다음 wrokgroupA를 선택하자.

(참고로 현재 실습은 버지니아 북부에서 진행 중이다!)

쿼리를 실행해보면 실행 불가!

실행했던 쿼리문이다..

/* Let's try to find the products and their corresponding category by number of reviews and avg star rating on parquet table */

SELECT product_id, product_category, product_title, count(*) as num_reviews, avg(star_rating) as avg_stars
FROM amazon_reviews_parquet 
GROUP BY 1, 2, 3
ORDER BY 4 DESC
limit 10;

 

다음으로 workgroupB로 전환하고 userA가 workgroupB에서 동일한 쿼리를 실행할 수 있는지 확인해보자.

권한이 없어 할 수 없다는 오류가 발생한다.

 

 

'Cloud > AWS' 카테고리의 다른 글

[AWS] AppStream 2.0  (0) 2022.11.26
[AWS] Amazon QuickSight 개념 및 실습  (0) 2022.11.20
[AWS] Amazon Athena 사용법 -2 + Glue(Crawler) 활용  (1) 2022.11.19
[AWS] Amazon Athena 사용법 -1  (1) 2022.11.19
[AWS] Step Functions  (0) 2022.11.18

Athena 사용법: https://realyun99.tistory.com/147

 

[AWS] Amazon Athena 사용법

먼저 Athena가 뭐하는 친군지 살펴보자. Amazon Athena 표준 SQL을 사용해 S3에 저장된 데이터를 간편하게 분석할 수 있는 대화식 쿼리 서버리스 서비스 그냥 단순히 S3에 저장된 데이터를 가리키고 스

realyun99.tistory.com

저번 포스팅에 이어서 Glue까지 사용을 해보자. 사용 전에 Glue가 뭔지 부터 확인하자.

 


AWS Glue

  • 분석, 기계 학습 및 애플리케이션 개발을 위해 데이터를 쉽게 탐색, 준비, 조합할 수 있도록 지원하는 서버리스 데이터 통합 서비스
  • 데이터 통합: 해당 개발을 위해 데이터를 준비하고 결합하는 프로세스
    • 데이터 검색 및 추출
    • 데이터 강화, 정리, 정규화 및 결합
    • 데이터베이스, 데이터 웨어하우스 및 데이터 레이크에 데이터 로드 및 구성 등
  • 기능
    • Data Catalog: 모든 데이터 자산을 위한 영구 메타데이터 스토어
      • 모든 AWS 데이터 세트에서 검색: 자동으로 통계를 계산하고 파티션을 등록, 데이터 변경 사항 파악
      • Crawlers: 소스/대상 스토어에 연결해 우선순위가 지정된 Classifiers을 거치면서 데이터의 스키마 결정, 메타 데이터 생성
      • Stream schema registries: Apache Avro 스키마를 사용해 스트리밍 데이터의 변화를 검증하고 제어
    • Data Integration and ETL(Extract / Transform / Load)
      • Studio Job Notebooks: Studio에서 최소한으로 설정할 수 있는 서버리스 노트북
      • Interactive Sessions: 데이터 통합 작업 개발을 간소화, 엔지니어와 대화식으로 데이터 탐색, 준비
      • ETL 파이프라인 구축: 여러 개의 작업을 병렬로 시작하거나 작업 간에 종속성을 지정
      • Studio: 분산 처리를 위한 확정성이 뛰어난 ETL 작업 가능, 에디터에서 ETL 프로세스를 정의하면 Glue가 자동으로 코드 생성
      • 등등...
    • Glue DataBrew: 시각적 데이터 준비 도구(사전 빌드된 250개 이상의 변환 구성 중 선택해서 코드 없이 가능)


솔직히 뭐라고 하는지 모르겠다.. 직접 써보는게 답!

Crawler로 실습을 진행해보자.

 

  • Glue로 테이블 만들기

크롤러를 생성해주자.

데이터 스토어는 저번 포스팅 때 가져왔었던 데이터셋이 위치한 버킷으로 지정할 것!

Create new IAM role을 통해 새로 생성하고 지정해준다. 타겟 DB까지 정해주면 끝!

크롤러를 돌려주자(생성된 크롤러 선택 후 Run 버튼 클릭)

Glue → Tables에 들어가면 테이블이 하나 더 추가된 것을 볼 수 있다.

Athena로 돌아가 다음 쿼리를 실행해 데이터를 확인해보자.

select * from amazon_review_glue_parquet limit 10;

 

  • Views 만들기

다시 Athena로 돌아왔다.(Athena의 view는 물리적 테이블이 아닌 논리적 테이블!)

저장된 쿼리에서 Athena_create_view_top_rated를 클릭한다.

위 이미지 처럼 선택 후 실행한다. 아래와 같이 보기에 추가된 것을 확인할 수 있다.

두번째 쿼리를 선택한 뒤 실행해 등급별로 상위 10개 제품을 확인해보자.

 

  • 결과 확인(S3 버킷)

S3에서 athena-workshop-<account-id> 로 시작하는 버킷을 찾아 들어가면 처음엔 비어있던 버킷이 Athena에서 돌렸던 쿼리문을 기준으로 폴더들이 생성되어 있는 것을 볼 수 있고, Athena_compare_reviews 접두사 중 하나를 찾아보면 쿼리 ID와 함께 저장된 결과를 볼 수 있음.

 

 

 

❗ 그래서 결과적으로 Glue Crawler가 무슨 역할을 했냐...? ❗

크롤러 작동 방식:

데이터를 분류하여 raw data의 포맷, 스키마 및 관련 속성 결정 / 데이터를 테이블 혹은 파티션으로 분류 / 메타데이터를 Data Catalog에 작성

 

위와 같은 것들을 crawler를 생성하고 실행하면 알아서 해주는 느낌인듯?

데이터 스토어를 지금은 하나를 지정했지만, 여러 개 병렬로도 가능하고...

지금 했던 실습 같은 경우는 아주 단순한 경우인 거고, 여러 방식으로 활용이 가능하다!

(그리고 Athena는 쿼리를 돌려서 테이블을 만들었지만, 크롤러는 그런게 없이 알아서 돌려주네?!)

'Cloud > AWS' 카테고리의 다른 글

[AWS] Amazon QuickSight 개념 및 실습  (0) 2022.11.20
[AWS] Amazon Athena 사용법 -3  (0) 2022.11.20
[AWS] Amazon Athena 사용법 -1  (1) 2022.11.19
[AWS] Step Functions  (0) 2022.11.18
[AWS] Spot Fleet  (0) 2022.11.16

먼저 Athena가 뭐하는 친군지 살펴보자.


Amazon Athena

  • 표준 SQL을 사용해 S3에 저장된 데이터를 간편하게 분석할 수 있는 대화식 쿼리 서버리스 서비스
  • 그냥 단순히 S3에 저장된 데이터를 가리키고 스키마를 정의한 후 표준 SQL을 사용하여 쿼리를 시작하면 됨
  • AWS Glue Data Catalog와 즉시 통합됨
    • 다양한 서비스에 걸쳐 통합된 메타데이터 리포지토리를 생성하고, 데이터 원본을 크롤링하여 스키마를 검색하고 카탈로그를 신규 및 수정된 테이블 정의와 파티션 정의로 채우며, 스키마 버전을 관리할 수 있음
  • 기능
    • 표준 SQL을 사용한 간편한 쿼리: 오픈 소스 분산 SQL 쿼리 엔진(Presto) 사용
    • 쿼리당 비용 지불: 실행한 쿼리에 대한 비용 지불(각 쿼리에서 스캔한 데이터 양에 따라 요금 부과)
    • 빠른 성능: 자동으로 쿼리를 병렬로 실행, 대규모 데이터 세트에서도 빠른 결과 얻음
    • 기계학습: SQL 쿼리에서 SageMaker 기계학습 모델을 호출하여 추론 실행 가능

등.. 많은 기능이 있다! 그러면 이러한 좋은 서비스 Athena를 사용해볼까?


aws workshop을 따라 가는 중..

  • CloudFormation

CloudFormation(버지니아 북부)를 통해 밑바탕을 깔자.

(template)

더보기

# Purpose:  Creates Athena Workgroups, Named Queries, IAM Users via AWS CloudFormation
#===============================================================================
AWSTemplateFormatVersion: "2010-09-09"
Description: |
  Athena Immersion Day - Creates Athena Workgroups, Named Queries, IAM Users

Resources:
  AthenaWorkShopBucket:
    Type: "AWS::S3::Bucket"
    Properties: 
      BucketName: !Join [ "-", ["athena-workshop", Ref: "AWS::AccountId"]] 

  workgroupA:
    Type: AWS::Athena::WorkGroup
    Properties:       
      Name: workgroupA
      RecursiveDeleteOption: true
      WorkGroupConfiguration:
        PublishCloudWatchMetricsEnabled: true
        ResultConfiguration:
          OutputLocation: !Join [ "", ["s3://" , Ref: AthenaWorkShopBucket, "/"]]

  workgroupB:
    Type: AWS::Athena::WorkGroup
    Properties:       
      Name: workgroupB
      RecursiveDeleteOption: true

  
  workgroupIcebergpreview:
    Type: AWS::Athena::WorkGroup
    Properties:       
      Name: AmazonAthenaIcebergPreview
      RecursiveDeleteOption: true
      WorkGroupConfiguration:
        EnforceWorkGroupConfiguration: true
        EngineVersion:
         SelectedEngineVersion: Athena engine version 2       
        PublishCloudWatchMetricsEnabled: true
        ResultConfiguration:
          OutputLocation: !Join [ "", ["s3://" , Ref: AthenaWorkShopBucket, "/"]]

  amazonreviewstsv:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "Create table amazon_reviews_tsv"
      Name: "Athena_create_amazon_reviews_tsv"
      QueryString: |
                    CREATE EXTERNAL TABLE amazon_reviews_tsv (
                    marketplace string, 
                    customer_id string, 
                    review_id string, 
                    product_id string, 
                    product_parent string, 
                    product_title string, 
                    product_category string, 
                    star_rating int, 
                    helpful_votes int, 
                    total_votes int, 
                    vine string, 
                    verified_purchase string, 
                    review_headline string, 
                    review_body string, 
                    review_date date,
                    year int)
                    ROW FORMAT DELIMITED
                    FIELDS TERMINATED BY '\t'
                    ESCAPED BY '\\'
                    LINES TERMINATED BY '\n'
                    LOCATION
                    's3://amazon-reviews-pds/tsv/'
                    TBLPROPERTIES ("skip.header.line.count"="1");  

  amazonreviewsparquet:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "Create table amazon_reviews_parquet"
      Name: "Athena_create_amazon_reviews_parquet"
      QueryString: |
                    CREATE EXTERNAL TABLE amazon_reviews_parquet(
                    marketplace string, 
                    customer_id string, 
                    review_id string, 
                    product_id string, 
                    product_parent string, 
                    product_title string, 
                    star_rating int, 
                    helpful_votes int, 
                    total_votes int, 
                    vine string, 
                    verified_purchase string, 
                    review_headline string, 
                    review_body string, 
                    review_date bigint, 
                    year int)
                    PARTITIONED BY (product_category string)
                    ROW FORMAT SERDE 
                    'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
                    STORED AS INPUTFORMAT 
                    'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
                    OUTPUTFORMAT 
                    'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
                    LOCATION
                    's3://amazon-reviews-pds/parquet/'; 

                    /* Next we will load the partitions for this table */
                    MSCK REPAIR TABLE amazon_reviews_parquet;

                    /* Check the partitions */
                    SHOW PARTITIONS amazon_reviews_parquet;

  qryamazonreviewstsv:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "Reviews Ratings table amazon_reviews_tsv"
      Name: "Athena_compare_reviews"
      QueryString: |
                    /* Let's try to find the products and their corresponding category by number of reviews and avg star rating */
                    SELECT product_id, product_category, product_title, count(*) as num_reviews, avg(star_rating) as avg_stars
                    FROM amazon_reviews_tsv 
                    GROUP BY 1, 2, 3
                    ORDER BY 4 DESC
                    limit 10;

                    /* Let's try to find the products and their corresponding category by number of reviews and avg star rating on parquet table */
                    SELECT product_id, product_category, product_title, count(*) as num_reviews, avg(star_rating) as avg_stars
                    FROM amazon_reviews_parquet 
                    GROUP BY 1, 2, 3
                    ORDER BY 4 DESC
                    limit 10;
                    
                    /* Let's try to find the products by number of reviews and avg star rating in Mobile_Apps category */
                    SELECT product_id, product_title, count(*) as num_reviews, avg(star_rating) as avg_stars
                    FROM amazon_reviews_tsv where product_category='Mobile_Apps'
                    GROUP BY 1, 2
                    ORDER BY 3 DESC
                    limit 10;

                    /* Let's try to find the products by number of reviews and avg star rating in Mobile_Apps category */
                    SELECT product_id, product_title, count(*) as num_reviews, avg(star_rating) as avg_stars
                    FROM amazon_reviews_parquet where product_category='Mobile_Apps'
                    GROUP BY 1, 2
                    ORDER BY 3 DESC
                    limit 10;

  TopReviewedStarRatedProductsv:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "Create View TopRatedProducts"
      Name: "Athena_create_view_top_rated"
      QueryString: |
                    CREATE view topratedproducts AS
                    SELECT product_category,
                            product_id,
                            product_title,
                            count(*) count_reviews
                    FROM amazon_reviews_parquet
                    WHERE star_rating=5
                    GROUP BY  1, 2, 3
                    ORDER BY  4 desc;

                    Select * from topratedproducts limit 10;

  ctas:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "CTAS Amazon Reviews by Marketplace"
      Name: "Athena_ctas_reviews"
      QueryString: |
                    CREATE TABLE amazon_reviews_by_marketplace
                    WITH ( format='PARQUET', parquet_compression = 'SNAPPY', partitioned_by = ARRAY['marketplace', 'year'], 
                    external_location =   's3://<<Athena-WorkShop-Bucket>>/athena-ctas-insert-into/') AS
                    SELECT customer_id,
                            review_id,
                            product_id,
                            product_parent,
                            product_title,
                            product_category,
                            star_rating,
                            helpful_votes,
                            total_votes,
                            verified_purchase,
                            review_headline,
                            review_body,
                            review_date,
                            marketplace,
                            year(review_date) AS year
                    FROM amazon_reviews_tsv
                    WHERE "$path" LIKE '%tsv.gz';

                    /* Let's try to find the products and their corresponding category by number of reviews and avg star rating for US marketplace in year 2015 */

                    SELECT product_id,
                            product_category,
                            product_title,
                            count(*) AS num_reviews,
                            avg(star_rating) AS avg_stars
                    FROM amazon_reviews_by_marketplace
                    WHERE marketplace='US'
                    AND year=2015
                    GROUP BY  1, 2, 3
                    ORDER BY  4 DESC limit 10; 

  comparereviews:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "Compare query performance"
      Name: "Athena_compare_reviews_marketplace"
      QueryString: |
                    SELECT product_id, COUNT(*) FROM amazon_reviews_by_marketplace
                    WHERE marketplace='US' AND year = 2013
                    GROUP BY 1 ORDER BY 2 DESC LIMIT 10;

                    SELECT product_id, COUNT(*) FROM amazon_reviews_parquet
                    WHERE marketplace='US' AND year = 2013
                    GROUP BY 1 ORDER BY 2 DESC LIMIT 10;

                    SELECT product_id, COUNT(*) FROM amazon_reviews_tsv
                    WHERE marketplace='US' AND extract(year from review_date) = 2013
                    GROUP BY 1 ORDER BY 2 DESC LIMIT 10;
  
  flights:
    Type: AWS::Athena::NamedQuery
    Properties:
      Database: "default"
      Description: "Top 10 routes delayed by more than 1 hour"
      Name: "Athena_flight_delay_60"
      QueryString: |
                    SELECT origin, dest, count(*) as delays
                    FROM flight_delay_parquet
                    WHERE depdelayminutes > 60
                    GROUP BY origin, dest
                    ORDER BY 3 DESC
                    LIMIT 10;

  LabsUserPassword:
    Type: "AWS::SecretsManager::Secret"
    Properties:
      Description: Athena Workshop User Password
      Name: "/athenaworkshopuser/password"
      GenerateSecretString:
        SecretStringTemplate: '{}'
        GenerateStringKey: "password"
        PasswordLength: 30

  userA:
    Type: "AWS::IAM::User"
    Properties: 
      Path: "/"
      LoginProfile: 
        Password: !Sub '{{resolve:secretsmanager:${LabsUserPassword}:SecretString:password}}'
        PasswordResetRequired: false
      Policies: 
        - PolicyName: "Athena-WorkgroupA-Policy"
          PolicyDocument: 
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action:
              - s3:Put*
              - s3:Get*
              - s3:List*
              - glue:*
              - cloudwatch:*
              - athena:ListNamedQueries
              - athena:ListWorkGroups
              - athena:GetExecutionEngine
              - athena:GetExecutionEngines
              - athena:GetNamespace
              - athena:GetCatalogs
              - athena:GetNamespaces
              - athena:GetTables
              - athena:GetTable
              Resource: "*"
            - Effect: Allow
              Action:
              - athena:StartQueryExecution
              - athena:GetQueryResults
              - athena:DeleteNamedQuery
              - athena:GetNamedQuery
              - athena:ListQueryExecutions
              - athena:StopQueryExecution
              - athena:GetQueryResultsStream
              - athena:ListNamedQueries
              - athena:CreateNamedQuery
              - athena:GetQueryExecution
              - athena:BatchGetNamedQuery
              - athena:BatchGetQueryExecution
              Resource:
              - !Join [ "", ["arn:aws:athena:us-east-1:", Ref: "AWS::AccountId" , ":workgroup/workgroupA"]]              
            - Effect: Allow
              Action:
              - athena:DeleteWorkGroup
              - athena:UpdateWorkGroup
              - athena:GetWorkGroup
              - athena:CreateWorkGroup
              Resource:
              - !Join [ "", ["arn:aws:athena:us-east-1:", Ref: "AWS::AccountId" , ":workgroup/workgroupA"]]
      UserName: "userA"

  userB:
    Type: "AWS::IAM::User"
    Properties: 
      Path: "/"
      LoginProfile: 
        Password: !Sub '{{resolve:secretsmanager:${LabsUserPassword}:SecretString:password}}'
        PasswordResetRequired: false
      Policies: 
        - PolicyName: "Athena-WorkgroupA-Policy"
          PolicyDocument: 
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action:
              - s3:Put*
              - s3:Get*
              - s3:List*
              - glue:*
              - athena:ListWorkGroups
              - athena:GetExecutionEngine
              - athena:GetExecutionEngines
              - athena:GetNamespace
              - athena:GetCatalogs
              - athena:GetNamespaces
              - athena:GetTables
              - athena:GetTable
              Resource: "*"
            - Effect: Allow
              Action:
              - athena:StartQueryExecution
              - athena:GetQueryResults
              - athena:DeleteNamedQuery
              - athena:GetNamedQuery
              - athena:ListQueryExecutions
              - athena:StopQueryExecution
              - athena:GetQueryResultsStream
              - athena:ListNamedQueries
              - athena:CreateNamedQuery
              - athena:GetQueryExecution
              - athena:BatchGetNamedQuery
              - athena:BatchGetQueryExecution
              Resource:
              - !Join [ "", ["arn:aws:athena:us-east-1:", Ref: "AWS::AccountId" , ":workgroup/workgroupB"]]              
            - Effect: Allow
              Action:
              - athena:DeleteWorkGroup
              - athena:UpdateWorkGroup
              - athena:GetWorkGroup
              - athena:CreateWorkGroup
              Resource:
              - !Join [ "", ["arn:aws:athena:us-east-1:", Ref: "AWS::AccountId" , ":workgroup/workgroupB"]]
      UserName: "userB"  
    
Outputs:
  S3Bucket:
    Description: S3 bucket
    Value: !Ref AthenaWorkShopBucket

  ConsoleLogin:
    Description: LoginUrl
    Value: !Join ["", ["https://", Ref: "AWS::AccountId" , ".signin.aws.amazon.com/console"]]

  ConsolePassword:
    Description: AWS Secrets URL to find the generated password for User A and User B
    Value: !Sub 'https://console.aws.amazon.com/secretsmanager/home?region=${AWS::Region}#/secret?name=/athenaworkshopuser/password'  

스택의 리소스나 이벤트를 확인해보면 생성 결과 → 쿼리문 파일들 + Athena 작업그룹 + IAM User A/B + S3 버킷 정도?

사실 이번 포스팅에서 User를 나누는 의미는 없다. 나중에 이어서 실습할 내용들에 있어서 필요한 유저들..

 

  • Dataset 확인

데이터셋은 workshop에서 제공해주는 s3 버킷에 담겨있다.

더보기

https://console.aws.amazon.com/s3/home?region=us-east-1&bucket=amazon-reviews-pds

 

  • Athena 기본 설정

작업 그룹에 대해 CloudWatch 지표를 활성화 한다.

CloudFormation을 통해 만들어진 작업 그룹들이다. 현재는 primary 기준으로 진행할 것!

(primary → 편집)

쿼리들을 실행하기 전에 먼저 Athena 설정에서 S3 버킷을 지정해줘야한다.

쿼리 편집기 → 설정보기

CloudFormation에서 생성했던 s3로 지정해준다.

 

  • Athena - 테이블 생성 및 쿼리 실행

default 데이터베이스에서 실행할 예정. 만약 데이터베이스가 없다면 'CREATE database default' 실행.

저장된 쿼리에서 Athena_create_amazon_review_tsv를 클릭후 편집기에 해당 쿼리문이 열리면 실행하자.

위 이미지와 같이 테이블이 만들어지면 성공

 

다음으론 저장된 쿼리에서 Athena_create_amazon_reviews_parquet를 클릭.

쿼리문에서 한 번에 하나의 쿼리를 선택하고 실행하자.(주석 기준으로 나눠서 드래그 후 실행)

딱 여기까지.. 다음 쿼리문들은 파티셔닝 관련 명령이다.

테이블 하나 더 생김!

 

  • Athena - Partitioning Data

데이터를 분할하여 각 쿼리에서 스캔하는 데이터의 양을 제한하여 성능을 개선하고 비용을 절감할 수있음.

모든 키로 데이터를 분할할 수 있다. (보통 시간을 기준으로 데이터를 분할)

- 참고: https://docs.aws.amazon.com/ko_kr/athena/latest/ug/partitions.html

 

그럼 amazon_reviews_parquet 테이블을 기준으로 파티셔닝을 해보자.

위와 같이 두 명령을 각각 실행해보자.

그러면 파티션 추가 완료.

 

  • Athena - 테이블 간 성능 테스트

저장된 쿼리에서 Athena_compare_reviews를 열자.

쿼리를 하나씩 선택해서 실행해 각 결과를 비교해보자.(스캔한 데이터 양과 소요 시간 차이 확인)

 

파티셔닝 전의 테이블: amazon_reviews_tsv

평균 리뷰별 상위 10개 제픔
모바일 앱 카테고리의 평균 리뷰 기준 상위 10개 제품

파티셔닝 후의 테이블: amazon_reviews_parquet

평균 리뷰별 상위 10개 제품
모바일 앱 카테고리의 평균 리뷰 기준 상위 10개 제품

 

확실히 파티셔닝 후의 테이블의 성능이 뛰어나다는 것을 확인할 수 있다.

 

 

기본적인 SQL문(Select From 뭐시기... 이런 것)들은 알고 있는데..

파티셔닝 관련한 명령은 알지 못해서.. 간단히 정리해본다.

 

파티션을 사용하는 테이블을 생성하려면 CREATE TABLE 문에 PARTITIONED BY 절을 사용

기본 문법:

CREATE EXTERNAL TABLE users (
first string,
last string,
username string
)
PARTITIONED BY (id string)
STORED AS parquet
LOCATION 's3://DOC-EXAMPLE-BUCKET/folder/'

테이블을 생성하고 쿼리를 위해 파티션에 데이터를 로드하는 명령

(참고로 parquet(파켓)은 Apache Hadoop 에코 시스템의 오픈소스 열 지향 데이터 저장 형식)

이후에 Hive 스타일 파티션의 경우 MSCK REPAIR TABLE을 실행(지금 했던 방식)

아니라면 ALTER TABLE ADD PARTITON을 사용해 파티션을 수동으로 추가

CREATE EXTERNAL TABLE amazon_reviews_parquet(
marketplace string, 
customer_id string, 
review_id string, 
product_id string, 
product_parent string, 
product_title string, 
star_rating int, 
helpful_votes int, 
total_votes int, 
vine string, 
verified_purchase string, 
review_headline string, 
review_body string, 
review_date bigint, 
year int)
PARTITIONED BY (product_category string)
ROW FORMAT SERDE 
'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
's3://amazon-reviews-pds/parquet/'; 

/* Next we will load the partitions for this table */
MSCK REPAIR TABLE amazon_reviews_parquet;

/* Check the partitions */
SHOW PARTITIONS amazon_reviews_parquet;

위의 코드블럭은 실습 진행하면서 사용했던 쿼리문이다.(어렵다 어려워...)

 

 

 

❗ 다음 포스팅에선 Glue와 어떤 식으로 통합해 사용하는지 알아보자 ❗

'Cloud > AWS' 카테고리의 다른 글

[AWS] Amazon Athena 사용법 -3  (0) 2022.11.20
[AWS] Amazon Athena 사용법 -2 + Glue(Crawler) 활용  (1) 2022.11.19
[AWS] Step Functions  (0) 2022.11.18
[AWS] Spot Fleet  (0) 2022.11.16
[AWS] Lambda와 RDS Proxy  (0) 2022.11.14

Step Fuctions 작동 원리

  • Step Functions 상태머신: 실행될 워크플로우를 선언적으로 정의하는 그래프
    • 하나의 워크플로우는 여러 개의 작업 단위로 구성될 수 있음
    • Action: Lambda  함수 호출, SNS로의 publish, ECS task 실행 등과 같은 다른 AWS 서비스를 활용하여 작업 수행
    • Flow: task들의 제어 흐름을 정의하는 7가지 상태
      • Choice: 조건문에 따른 분기를 정의
      • Parallel: 동일 입력에 대해 여러 작업을 병렬 처리
      • Map: 배열과 같은 Iterable 입력에 대해 task의 동적 병렬 처리를 수행
      • Pass: 디버깅 / Wait: 타이머 기능 / Success/Fail: 실행 성공 여부 확인
    • Action과 Flow의 조합으로 Start 상태부터 End 상태까지 다양한 워크플로우를 쉽게 정의
  • 모니터링: try - catch - finally 패턴을 통해 timeout, retry, error message 등을 한번에 관리 가능
  • 자동 스케일링, 고가용성 제공

 

Step Functions 개발 옵션

  • Workflow Studio:
    • GUI 인터페이스만으로 워크플로우 배포 가능
    • Production 환경에서 얘만 사용하면 유지보수에 어려움이 있을 수 있음
  •  IaC 프레임 워크 활용: AWS CDK, Terraform + 서버리스 개발용 라이브러리: AWS Chalice(파이썬)
    • 위의 상황은 디커플링된 상태: 애플리케이션과 인프라가 디커플링
    • 각 각에 대해 코드 수정을 해야하는 비효율성이 생길 수 있음
  • 애플리케이션과 인프라를 커플링 → 서버리스 프레임워크

 

개발 팁

  • 서비스 할당량
    • 소프트 할당량(별도의 요청으로 상한을 올릴 수 있음) / 하드 할당량(상한을 올릴 수 없음)
    • 자주 접할 수 있는 하드 할당량:
      • 페이로드의 최대 크기: 256KB 넘길 수 없음
        • 상태머신의 페이로드는 필수 정보, 상태 정보 등.. 
        • 이외의 데이터는 다른 서비스나 서버에 저장 후 불러와라
          • (S3, DynamoDB, Aurora, Kinesis Data Streams, SQS)
      • 실행 기록의 최대 이벤트 개수: 최대 25000개 까지 기록(넘어가면 실행 즉시 실패)
        • 이벤트 개수 줄이기 → 비추천
        • Lambda 함수를 통해 상태머신 재실행(AWS 측 추천)
          • 워크플로우 과정 중 현재 실행의 실행기록이 최대치에 근접할 때, 상태머신 재실행 하는 판단 부분 삽입
          • 해당 진행사항을 저장하는 부분도 필요함: 재실행할 때 정보가 변하면 안됨!
  • 동적 병렬처리
    • MaxConcurrency: 동시 실행 가능한 작업자의 최대 개수
    • Map 상태가 최대 동시성 값에 따라 병렬로 실행할 작업자의 개수를 결정
    • 문제: 작업의 동적할당을 위해선 작업을 배열의 형태로 만들어야함. 근데 페이로드 안에 다 있어야하니까.. 최대 페이로드 크기에 걸릴 수 있음
      • 전체 작업을 처리 가능한 크기의 작업으로 분할 후 반복실행을 통해 순차적으로 처리 
  • 외부 서비스 통합: Activity Worker 패턴 이용
    •  동기적으로 처리하기 위함..
    • Activity: 상태머신의 진행을 비동기적으로 바꾸기 위함
      • 상태머신이 Activity 대기 상태로 들어가면 해당 Activity 하위에 새로운 작업을 생성 후 실행을 잠시 정지 시킴
      • AWS SDK를 활용해 GetActivityTask 호출:
        • 지정한 Activity에 처리되지 않은 작업이 있으면 해당 작업을 할당받음과 동시에 작업의 입력값과 토큰을 받음
        • 이후 전달받은 입력값으로 완료되면 SendTaskSuccess를 이용해 작업의 성공을 알림
      • 생성한 작업이 완료되면 대기 상태 해체 후 실행 재개

 

 

 

❗ 솔직히 AWS 내에서 서버리스로 다 구성하려면... 이거 활용하면 좋을듯!!! ❗

'Cloud > AWS' 카테고리의 다른 글

[AWS] Amazon Athena 사용법 -2 + Glue(Crawler) 활용  (1) 2022.11.19
[AWS] Amazon Athena 사용법 -1  (1) 2022.11.19
[AWS] Spot Fleet  (0) 2022.11.16
[AWS] Lambda와 RDS Proxy  (0) 2022.11.14
[AWS] EC2 인스턴스 자동 중지 및 시작  (0) 2022.11.13

GPU 인스턴스를 사용할 때 스팟 인스턴스를 많이들 활용한다고 한다. 비용 때문이다!

근데, GPU 인스턴스의 경우 GPU 리소스의 부족 현상이 있을 수 있음...😅


Spot Fleet

  • 사용자가 지정한 기준에 따라 시작되는 스팟 인스턴스의 집합(선택적으로 온디맨드 설정 가능)
  • 요청 유형
    • request: 원하는 용량을 얻기 위한 비동기식 일회성 요청(목표 용량 유지 비활성화)
    • maintain: 원하는 용량을 얻기 위한 비동기식 요청, 중단된 모든 스팟 인스턴스를 자동으로 보충해 용량 유지(목표용량 유지 활성화)

  • 인터럽트 방식: 스팟 서비스가 중단된 스팟 인스턴스 처리 방식(종료 / 중지 / 최대 절전 모드(수면))
  • 용량 재조정:
    • 시작 전용: 기존 스팟 인스턴스에 대해 재조정 알림이 전송될 때 대체 스팟 인스턴스 시작
      • 이전 인스턴스를 종료하거나 실행 중인 상태로 두는 건 사용자의 선택
    • 종료 전 시작: 새로운 대체 스팟 인스턴스가 시작된 후 재조정 알림을 받는 스팟 인스턴스 종료(termination-delay)
      • 인스턴스 종료 절차가 완료되는데 걸리는 시간 예측 가능할 때 사용

  • 할당 방식
    • 가격 용량 최적화(priceCapacityOptimized): 가용성이 가장 높은 풀 안에서 가장 저렴한 가격
      • 여기서 말하는 가용성은 중단 가능성이 가장 낮음을 말한다
    • 용량 최적화(capacityOptimized): 가용성이 가장 높은 풀 식별, 유형에 대한 우선 순위 설정 가능
    • 최저 가격(lowestPrice): 사용 가능한 용량이 있는 최저 가격 풀에서
    • 모든 풀에서 다각화(diversified): 모든 풀에 분산
  • 단점
    • 아무래도 스팟 인스턴스다 보니... 언제 중단될 지 모른다. 종료 2분 전 경고 알림
    • maintain이라는 유형이 있긴 하지만.. GPU 인스턴스의 경우 말이 다르다! GPU 리소스에 대한 수요가 높아 부족할 수도 있기 때문이다.

 

위의 단점을 피하기 위해 스팟 플릿에 대한 모니터링은 필수다!

EventBridge 서비스를 활용해 알림을 받을 수 있게 규칙을 설정해두는 걸 추천!

해당 이벤트 패턴에 Spot Fleet 알림 받는 소스를 제공해준다!

알림 대상을 SNS 주제로 설정해도 괜찮고 다른 여러 서비스들이 있으니 잘 활용하면 좋을 듯:)

CloudWatch로 트리거 잡아 Lambda로 설정해도 괜찮은데.. 귀찮잖아~

 

 

'Cloud > AWS' 카테고리의 다른 글

[AWS] Amazon Athena 사용법 -1  (1) 2022.11.19
[AWS] Step Functions  (0) 2022.11.18
[AWS] Lambda와 RDS Proxy  (0) 2022.11.14
[AWS] EC2 인스턴스 자동 중지 및 시작  (0) 2022.11.13
[AWS] GPU 인스턴스 Spot Fleet  (0) 2022.11.12

+ Recent posts