네이버 클라우드 플랫폼 서비스를 활용한 Spark ETL 및 데이터 시각화-2부

MyeongSu Kim
NAVER CLOUD PLATFORM
12 min readSep 1, 2020

--

오픈 데이터를 활용하여 Object Storage 데이터를 추출하고 변환하고 저장하는 작업을 이전 1부에서 수행하였습니다.

이번 시간에는 변환한 스키마를 토대로 다차원 데이터를 간단하게 분석하고, 분석된 데이터를 시각화하도록 하겠습니다.

주요 상품 설명

▶Cloud DB for MySQL 상품은 MySQL DB 구축 및 관리를 제공합니다.

▶Superset은 Server 상품의 Application 중 하나로 제공하며 간단한 시각화 환경을 구축할 수 있습니다.

▶Cloud Hadoop 상품은 Hadoop, HBase, Spark, Hive, Presto 등의 오픈 소스 프레임워크를 손쉽게 구축할 수 있습니다.

▶Object Storage 상품은 안전한 보관이 필요하거나, 대용량 데이터를 저장하는데 활용할 수 있으며, 제공되는 API를 사용하여 서버 데이터의 백업 및 복구 용도로도 활용할 수 있습니다.

※더욱 자세한 서비스 소개는 아래의 링크에서 확인 가능합니다!
Cloud DB for MySQL: https://www.ncloud.com/product/analytics/cloudHadoop
Superset: https://docs.ncloud.com/ko/das/das-0-2.html
Cloud Hadoop: https://www.ncloud.com/product/analytics/cloudHadoop
Object Storage: https://www.ncloud.com/product/storage/objectStorage

Movielens 다차원 분석을 위한 데이터 정보

테이블 생성 및 Hive Metastore 등록

먼저 이전에 생성한 Cloud Hadoop 클러스터에서 8000포트로 Hue 에 접속합니다.

Hive DDL을 활용하여 테이블들을 생성합니다.

CREATE EXTERNAL TABLE fact_ratings(
`userid` int ,
`movieid` int ,
`dateid` bigint ,
`timeid` bigint ,
`rating` double ,
`timestamp` int )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/fact_ratings/';
CREATE EXTERNAL TABLE fact_tags(
`userid` int ,
`movieid` int ,
`dateid` bigint ,
`timeid` bigint ,
`tag` string ,
`timestamp` int )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/fact_tags/';
CREATE EXTERNAL TABLE dim_movie(
`movieid` int ,
`title` string )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/dim_movie/';
CREATE EXTERNAL TABLE dim_genre(
`genreid` int ,
`genres` string )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/dim_genre/';
CREATE EXTERNAL TABLE assoc_moviegenre(
`movieid` int ,
`genreid` int )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/assoc_moviegenre/';
CREATE EXTERNAL TABLE dim_user(
`userid` int )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/dim_user/';
CREATE EXTERNAL TABLE dim_time(
`timeid` bigint ,
`hour` int ,
`minute` int ,
`second` int ,
`ampm` string ,
`shift` string ,
`subshift` string ,
`mealtime` string )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/dim_time/';
CREATE EXTERNAL TABLE dim_time(
`timeid` bigint ,
`hour` int ,
`minute` int ,
`second` int ,
`ampm` string ,
`shift` string ,
`subshift` string ,
`mealtime` string )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/dim_time/';
CREATE EXTERNAL TABLE dim_date(
`dateid` bigint ,
`date` string ,
`day` int ,
`dayofweek` int ,
`dayname` string ,
`month` int ,
`year` int ,
`quarter` int ,
`quartername` string ,
`isweekend` string )
STORED AS PARQUET
LOCATION 's3a://ncp-spark/movielens/parquet/dim_date/';

마트 데이터 저장소

다차원 데이터를 분석한 Mart 데이터를 저장할 저장소로 Cloud DB for MySQL 을 생성합니다.

엔진, 서버 타입 등 클러스터 생성을 위한 서버 설정을 합니다.

DB 설정을 합니다. 여기서는 편의상 Spark나 Superset에서 접속하기 위해 HOST(IP)를 %로 설정합니다.

DB를 생성합니다.

Status가 ‘운영중’ 상태로 변환 여부 및 DB에 접속을 위한 Private 도메인을 확인합니다.

데이터 분석

위에서 생성한 Hive Metastore 정보를 참고하여 Spark에서 다차원 데이터 분석을 합니다. (Hive나 Presto를 사용하여 분석 가능하며, 여기서는 Spark를 이용하겠습니다.)

간략하게 2018년도 월별 장르별 태그 수를 조회한 분석 데이터를 MySQL DB에 저장합니다.

먼저 MySQL DB에 접속하여 분석 데이터를 저장할 테이블을 생성합니다.

CREATE TABLE `tag_count_by_genre_per_month` (
`year` INT(11) NOT NULL,
`month` INT(11) NOT NULL,
`genres` VARCHAR(100) NOT NULL,
`cnt` BIGINT NOT NULL,
PRIMARY KEY (`year`,`month`, `genres`)
);

이후 Spark에서 분석한 결과 데이터를 MySQL DB에 저장합니다.

import java.util.Properties
import org.apache.spark.sql.SaveMode
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
val properties = new Properties()
properties.put(“user”, “user”)
properties.put(“password”, “test123!”)
properties.put(“driver”, “com.mysql.jdbc.Driver”)
val emptyDataFrame = hiveContext.sql(“””
SELECT tags.year, tags.month, dim_genre.genres, count(*) AS cnt
FROM (
SELECT fact_tags.movieid, dim_date.year, dim_date.month
FROM fact_tags, dim_date
WHERE 1=1
AND fact_tags.dateid = dim_date.dateid
AND dim_date.year = 2018
) tags, assoc_moviegenre, dim_genre
WHERE 1=1
AND tags.movieid = assoc_moviegenre.movieid
AND assoc_moviegenre.genreid = dim_genre.genreid
GROUP BY tags.year, tags.month, dim_genre.genres
“””)
emptyDataFrame.write.mode(SaveMode.Append).jdbc(“jdbc:mysql://db-4p9hd.cdb.ntruss.com:3306/movielens”, “tag_count_by_genre_per_month”, properties)

데이터 시각화

데이터 시각화를 위해 서버 상품내 Superset을 이용합니다.

이미지 타입을 Application으로 선택합니다.

서버 설정, 인증키 설정, 네트워크 접속 설정 단계를 거쳐 서버를 생성합니다.

서버 생성이 완료되면 서버에 접속합니다.

Superset은 docker로 실행되어 있고, Cloud DB for MySQL에 접속하려면 mysqlclient 설치가 필요하기 때문에 Superset docker 로 접속합니다.

아래 명령으로 docker 컨테이너 정보를 확인합니다.

docker ps

superset 컨테이너 ID나 이름으로 접속합니다.

docker exec -it superset_superset_1 bash

mysqlclient를 설치합니다.

pip install mysqlclient

exit 하여 접속한 도커 컨테이너에서 나갑니다.

exit

아래 명령어를 입력하여 계정 정보 및 비밀번호를 설정합니다.

superset-init

설정이 완료되면, 해당 서버에 18088 포트로 Superset에 접속하여 위에서 설정한 계정 정보로 로그인 합니다.

Superset 관련 궁금한 부분은 아래 공식 홈페이지를 확인합니다.

Apache Superset : https://superset.incubator.apache.org/

Sources -> Databases 를 누릅니다.

SQLAlchemy URI 형식에 맞추어 위에서 생성한 Cloud DB mysql 접속 정보를 넣습니다.

mysql+mysqldb://user:test123!@db-4p9hd.cdb.ntruss.com:3306/movielens

Test Connection을 눌러 MySQL에 접속이 가능한지 확인 및 기타 설정을 확인합니다. Save를 눌러 저장합니다.

생성한 database를 확인합니다.

상단 메뉴 Sources -> Tables에서 table을 생성합니다.

생성된 table을 선택하거나 상단 메뉴 Charts를 선택하여 차트를 생성합니다.

Superset은 여러 차트 타입을 제공하기 때문에 다양한 차트들을 만들어 볼 수 있습니다.

대시보드를 생성하고, 위에서 생성한 차트들을 대시보드에 추가 합니다.

MySQL에 저장한 마트 데이터들을 시각화까지 완료하였습니다.

마무리하며…

네이버 클라우드 플랫폼의 서비스들을 사용해서 손쉽게 분석 환경을 구성하여 간단하게 데이터 저장/변환/분석/시각화를 해보았습니다.

끝까지 읽어 주셔서 감사합니다.

--

--