Google Cloud Dataproc 사용하기
최유석
이 글에서는 Google Cloud Dataproc에 대해서 알아보겠다.
Google Cloud DataProc?
구글 클라우드 플랫폼에서 제공하는 매니지드 HADOOP, Spark(+ Hive, Pig) 클러스터 서비스로 사용자가 손쉽게 HADOOP또는 Spark 클러스터를 구성할 수 있다.
빠른 클러스터 구성
규모에 상관없이 HADOOP, Spark 클러스터 구성에 걸리는 시간이 90초이내로 빠른 속도로 클러스터를 구성할 수 있고 이를 활용해서 사용자는 데이터 처리 또는 분석을 위한 작업에서 빠른 연산이 가능하다.
비용 절감
매우 빠른 속도로 클러스터를 구성할 수 있고, 분당과금 정책을 적용하여 사용자가 원하는 시간만큼 클러스터를 구성해서 연산을 실행하고 클러스터를 내려도 추가적인 가격 부담이 없다.
클러스터에 다양한 VM 타입 지원
클러스터 구성에 Predefined 형태의 VM 머신 뿐만 아니라, 사용자가 CPU, Memory크기를 자유롭게 설정하여 사용할 수 있는 Custom Machine Type을 지원하여 각각의 Job에 최적화한 크기의 클러스터 구성을 할 수 있고, 사용에 약간의 제약은 있지만, 80%낮은 가격으로 인스턴스를 사용할 수 있는 Preemptible VM타입을 지원하여 각각의 Job에 더욱 비용 효율적인 클러스터의 구성을 할 수 있게 지원한다. 추가로 클러스터의 노드에 GPU를 Attach할 수 있기 때문에 GPU의 연산이 필요한 경우에도 쉽게 사용 할 수 있다.
*GPU는 Preemtible VM에는 지원되지 않는다.
구글 클라우드 서비스들과의 통합
단순하게 Dataproc 클러스터만 구성해서 사용할 수 있는게 아니라 BigQuery, Cloud Storage, Cloud Bigtable, Stackdriver Logging, Monitoring, 등과의 함께 통합된 서비스로 제공되기 때문에 더욱 유연한 사용을 가능하게 한다.
Dataproc 클러스터 구성 및 테스트하기
앞서 Google Cloud Dataproc에 대한 개념적인 부분에 대해서 간단하게 알아보았다. 이제 Dataproc 클러스터를 구성하고 구성한 클러스터에서 sparkSQL을 이용해서 쿼리를 실행해보자. 쿼리를 실행할 때 처음에는 Worker Node를 2개 구성해서 쿼리를 실행해보고 이후 100개로 노드 수를 늘려서 쿼리를 실행하고 더 큰 용량의 데이터에도 쿼리를 실행하여 Node 수 에 따라서 성능이 어떻게 달라지는지 확인해본다. 또한, Dataproc에서 사용한 동일 데이터와 쿼리를 이용해서 빅쿼리에서도 실행해보고 결과를 비교해보려고 한다.
데이터 준비하기
이 예제에서 사용할 데이터는 빅쿼리에서 공개 데이터셋으로 제공하는 데이터를 이용한다.
Dataproc 클러스터에서 Cloud Storage Connector를 Built-in 형태로 제공하기 때문에 Cloud Storage에 있는 데이터에 다이렉트로 액세스가 가능하다. 이를 이용해서 빅쿼리 공개 데이터셋에 있는 특정 테이블을 Cloud Storage로 Export하고 이렇게 Export한 데이터에 바로 접근하여 사용할 예정이다.
Node 수에 따라서 성능이 어떻게 변화하는 지 확인하기 위해 서로 크기가 다른 두 개의 테이블을 사용할 예정이다.
첫번째 테이블은 음악 앨범에 대한 플레이리스트 정보들이 기록되어 있으며, 테이블의 크기는 1.11GB, 총 12,304,975개의 Row를 가지고 있다.
두번째로 사용할 테이블은 위키미디아에서 관리하는 각종 위키관련사이트의 페이지 뷰수에 대한 정보가 기록된 테이블로 2012년 7월에 대한 데이터를 가지고 있다. 테이블의 크기는 119GB, 총 1,858,577,426개의 Row를 가지고 있다.
위의 빅쿼리 공개 데이터셋을 GCS에 Export하여 사용하기 위해 먼저, GCS에 Regional 클래스로 US central1리전을 지정하여 버켓을 생성하고
위의 테이블들을 Export할 폴더를 각각 생성한다.
빅쿼리 공개데이터 셋에서 예제에서 사용할 테이블 데이터를 위에서 생성한 GCS 버켓의 폴더에 각각 CSV형식으로 Export한다.
*빅쿼리에서 테이블 데이터 export는 단일파일 기준으로 1GB이하의 파일에 대해서만 export를 할 수 있다. 만약, 1GB이상의 크기의 테이블 데이터에 대해서는 와일드카드 “*” 문자를 이용한 export를 사용해야 한다. 이 와일드 카드 문자를 이용하여 export하면 데이터가 지정한 GCS 위치(버켓 또는 버켓 내부 폴더)로 자동으로 분할되어 저장된다.
Dataproc 클러스터 생성하기
프로젝트 생성, 과금 설정, API활성화 등에 대한 내용은 앞의 다른 글에서 많이 언급하였으니 생략한다. 해당 내용은 https://cloud.google.com/dataproc/docs/quickstarts/quickstart-console
을 참고하기 바란다.
Google Cloud Console의 좌측 상단 서비스탭에서 Dataproc페이지로 접속하고 페이지 중앙의 [Create cluster] 버튼을 클릭한다.
생성할 클러스터의 이름을 임의로 입력하고(여기서는 sparkcluster로 사용했다.) 나머지 부분은 기본값으로 생성한다.
Dataproc Cluster는 기본값으로 생성시 Master Node 1대, Worker Node 2대로 생성된다.
Master Node SSH 접속
앞서, 생성한 클러스터의 디테일 페이지에서 VM Instances탭으로 이동하고 클러스터 Master Node의 우측 SSH버튼을 클릭하여 SSH로 접속한다.
Spark SQL CLI실행
Master Node의 SSH에서 다음의 명령어를 실행하여 Spark SQL CLI를 실행한다.
$ spark-sql
Spark SQL CLI를 실행하였다.
Playlist테이블 생성하기
Spark SQL CLI에서 다음의 쿼리 명령어를 실행하여 앞에서 GCS로 export한 테이블 데이터 중 playlist 테이블을 생성한다.
CREATE TABLE playlist USING com.databricks.spark.csv OPTIONS (path "gs://버켓/playlists/*", header "true", inferSchema "true"); |
Playlist 테이블이 생성되었다.
Playlist 테이블에 쿼리 실행하기
앞에서 생성한 playlist테이블을 대상으로 아래와 같은 쿼리를 실행해보자.
SELECT * FROM playlist limit 10; |
생성한 playlist 테이블의 전체 레코드 중에서 10개의 레코드를 가져오는 쿼리이다.
쿼리를 실행하였다.
쿼리 실행에 21.918초가 소요되었으며 쿼리 실행의 결과가 프롬프트에 나타나는 것을 확인할 수 있다.
빅쿼리에서 playlist 테이블에 쿼리 실행하기
앞에 생성한 Dataproc 클러스터에서 spark-sql을 이용해 실행한 쿼리를 빅쿼리에서 실행해보자.
쿼리 실행에 2초가 소요된 것을 확인할 수 있다. 동일한 쿼리지만 별도 Sorting을 하지 않았기 때문에 값은 다르게 나오니 참고 바란다.
100개의 Worker Node에서 쿼리 실행하기
이제 앞에서 생성했던 Dataproc 클러스터의 Worker Node를 100개로 늘려서 쿼리를 실행하고 결과를 확인해보자. 쿼리는 앞에서 playlist테이블에 실행한 쿼리 외에도 용량이 큰 Wikimedia 테이블 데이터(119GB)를 기준으로 테이블을 생성하고 쿼리를 실행해본다. 또한, 동일한 쿼리를 빅쿼리에서도 실행해서 결과를 확인해보자.
앞에서 생성한 클러스터 디테일 페이지에서 Configuration 탭으로 이동하고 Edit를 클릭하여 Worker nodes
부분의 숫자를 2 -> 100으로 변경하고 Save버튼을 클릭하여 변경한 내용을 저장한다.
Node가 전부 생성될 때까지 약간의 시간이 지나면, 다음과 같이 100개의 Worker Node가 생성된 것을 확인할 수 있다.
Worker Node의 번호가 0에서 99까지 총 100개의 노드가 생성되었다.
100개의 Worker node 생성이 완료되면 다시 클러스터의 Master Node의 SSH로 접속하여 “spark-sql” 명령으로 Spark SQL CLI를 실행한다. Spark SQL CLI를 실행하였으면 먼저 앞에서 생성했던 playlist테이블에 실행했던 쿼리를 실행하고 결과를 확인해보자.
100개의 Worker Node에서 Playlist테이블에 쿼리 실행하기
아래는 Dataproc 클러스터의 Worker Node 수를 100개로 늘리고 위에서 playlist 테이블에 실행했던 쿼리를 실행한 결과이다.
쿼리가 실행된 결과를 보면 총 18.402초가 소요된 것을 확인할 수 있다. 대상이 되는 playlist 데이터의 크기가 1.11GB로 작기 때문에 큰 속도 차이는 나지 않는 것으로 보여진다.
대용량의 데이터에 쿼리 실행하기
이제 데이터의 크기가 큰 Wikimedia 테이블 데이터를 대상으로 쿼리를 실행해서 쿼리 성능을 확인해보자.
테이블 생성
아래의 테이블 생성 쿼리를 실행해서 Wikimedia테이블 데이터를 이용해서 wikitest라는 이름으로 테이블을 생성한다.
CREATE TABLE wikitest (year integer, month integer, day integer, wikimedia_project string, language string, title string, views integer) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 'gs://버켓명/wikitest/*'; |
테이블이 생성되었다.
Wikimedia(Wikitest) 테이블에 쿼리 실행하기
아래와 같은 쿼리를 실행하고 결과를 확인해보자. 실행 할 쿼리의 내용은 앞에서 생성한 wikitest테이블에서 language의 값이 “en”이고 titile에 “sydney”라는 값이 들어있는 모든 레코드를 조회하고 이를 그룹핑하며, 조회된 데이터에 대해서 각 페이지 별 뷰수를 합산하고 합산된 뷰수를 기준으로 정렬하여 10개의 결과를 보여주는 쿼리이다.
SELECT language,title,sum(views) AS total_views FROM wikitest WHERE language ='en' AND title like '% sydney %' GROUP BY language,title ORDER BY total_views DESC LIMIT 10; |
위의 쿼리를 실행한 결과이다.
쿼리 실행에 총 30.387초가 소요되었으며 정상적으로 쿼리가 실행된 것을 확인할 수 있다.
추가로 wikimedia 데이터에 대해서 기본 Dataproc 클러스터(Master Node 1대, Worker Node 2대) 구성으로 실행한 결과는 다음과 같으니 참고하기 바란다.
기본 클러스터 구성으로 쿼리 실행 시 635.981초가 소요된 걸 확인할 수 있다. 노드 수가 많아짐에 따라서 쿼리 성능에 큰 차이가 발생하는 것을 확인할 수 있다.
빅쿼리에서 wikimedia 테이블에 동일한 쿼리 실행하기
100개로 worker node를 가진 Dataproc 클러스터에서 실행한 쿼리를 빅쿼리에서 실행해보자.
100개 노드에서 실행에 30초 가량 소요된 쿼리가 빅쿼리에서는 쿼리 실행에 4.2초가 소요된 것을 확인할 수 있다.
Dataproc과 빅쿼리 쿼리 시간 비교
데이터 / 실행모듈 |
Dataproc(M1, W2) |
Dataproc(M1, W100) |
BigQuery |
playlist(1.11GB) |
21.918초 |
18.402초 |
2초 |
Wikimedia(119GB) |
635.981초 |
30.387초 |
4.2초 |
*M = Master Node, W = Worker Node
동일한 데이터에 대한 동일한 쿼리 실행 속도에서 빅쿼리가 월등하게 빠른 것을 확인할 수 있다.
마무리
처음 이 글을 작성하려고 했던 시점에는 Google Cloud Dataproc에 대한 내용만 기재하려고 하였으나, 예제에 적용할 만한 데이터를 찾다가 보니 빅쿼리의 공개 데이터셋을 이용하게 되었고 동일한 쿼리를 Dataproc와 빅쿼리에서 실행하면 어떤 결과가 나올지 궁금하여 실행해보았다. 각각 쿼리를 실행하고 결과를 보니 속도에서 매우 큰 차이를 보이는 것을 확인 할 수 있었다. 그로 인해 빅쿼리에서 쿼리를 실행한 부분에 대한 내용을 추가하게 되었다. 단순하게 위의 예제에서의 쿼리를 실행한 결과만 놓고 보면 엄청난 차이라고 볼 수 있지만, 각각의 서비스들이 가지는 특징과 기능, 사용목적, 과금 정책, 등이 모두 다르다. 따라서 각자의 사용환경에 따라서 필요한 서비스를 적용하는 것을 고려해야 할 것이다.
추가로 클라우드에서 최적화된 하둡 배포 아키텍쳐에 대한 부분에 대해서 더 알아보고 싶다면 http://bcho.tistory.com/1169 글을 참고하기 바란다.
참고링크
https://cloud.google.com/dataproc/docs/
https://cloud.google.com/dataproc/docs/concepts/custom-machine-types
https://cloud.google.com/dataproc/docs/concepts/preemptible-vms
https://cloud.google.com/dataproc/docs/connectors/cloud-storage