빅쿼리 스트리밍 데이터 로딩하기

 

최유석

 

개요

구글 빅쿼리에서는 비동기 처리방식인 Job을 통해서 데이터를 로딩하는 방법 외에도 실시간으로 데이터를 로딩 할 수 있는 방법으로 스트리밍(Streaming) API를 제공한다. 이 글에서는 구글 빅쿼리에서 제공하는 스트리밍 API를 이용해서 실시간으로 데이터를 로딩하는 방법을 알아보도록 하자.

 

스트리밍(Streaming) API

비동기 연산인 Job을 통한 데이터 로딩방식이 아닌 API형태로 tabledata().insertAll() 메소드를 제공하여 한번에 하나씩 레코드를 삽입하는 방법을 제공한다. 하나의 레코드에는 하나 또는 다수의 행을 포함할 수 있다. 

*레코드는 빅쿼리가 지원하는 데이터 타입으로 하나 이상, 다수의 데이터 필드에 대한 일종의 집합이다.

*스트리밍 API를 이용한 데이터 로딩은 partition table에 적용되지 않는다.

 

스트리밍 로딩의 할당량 정책(quota policy)

스트리밍 API를 사용한 데이터로딩은 실시간으로 처리되는 부분으로 Job의 데이터로딩(batch) 방법에 비해서 처리 가능한 데이터의 크기와 행의 수가 제한적이다.

  • 최대 행 사이즈 : 1MB
  • HTTP 요청 사이즈 제한 : 10MB
  • 초당 최대 입력 가능 행 수 : 테이블 당 100,000 행, 프로젝트 당 1,000,000 행
  • 요청당 최대 입력 가능 행 수 : 제한은 없으나, 최대 500 행을 권장
  • 초당 최대 바이트 크기 : 100MB

 

*스트리밍 데이터 로딩 시에 위의 정책을 초과하는 경우에 에러가 발생한다. 따라서 그러한 경우는 Job을 통한 데이터 로딩을 권장한다.


데이터 일관성 보장

데이터에 대한 일관성을 보장할 수 있는 옵션으로 각각의 입력 행에 대해서 insertId를 적용할 수 있다. insertId는 행 입력 시 최소1분 정도 빅쿼리가 기억하고 있게 된다.

*이미 입력된 행에 대해서 insertId를 통해 중복된 데이터는 추가로 입력되지 않으며, 만약 변경된 데이터(행)를 입력하면 해당 insertId를 가진 데이터(행)는 변경된 데이터(행)로 입력된다.

 

템플릿 테이블

templateSuffix 속성을 통해서 지정한 대상 테이블을 기본 템플릿으로 하여 같은 스키마를 가진 새로운 테이블을 자동으로 생성할 수 있다. 

templateSuffix의 값은 사용자가 임의로 설정할 수 있다.

<대상 테이블> + <templateSuffix> 형태로 새로운 테이블이 생성된다.

 

Tabledata: insertAll정의

Tabledata는 API형태로 제공되는 Resource type으로 스트리밍 데이터 로딩을 지원하는 insertAll 메소드를 포함하고 있다.

 

HTTP 요청(request) 기본형식

POST https://www.googleapis.com/bigquery/v2/projects/projectId/datasets/datasetId/tables/tableId/insertAll

POST요청으로 각각 해당되는 project, dataset, table ID를 설정하면 된다.

 

insertAll 권한 범위

스트리밍 요청을 할 때 VM인스턴스가 위의 각각의 권한 범위를 나타내는 URI중에서 

적어도 하나의 범위의 권한을 가지고 있어야 한다.

Google API 접근 범위에 대한 참고 https://developers.google.com/identity/protocols/googlescopes

 


Request body 구조

{
  "kind": "bigquery#tableDataInsertAllRequest",
  "skipInvalidRows": boolean,
  "ignoreUnknownValues": boolean,
  "templateSuffix": string,
  "rows": [
    {
      "insertId": string,
      "json": {
        (key): (value)
      }
    }
  ]
}

필수(Required) 속성

  • kind : 응답의 자원 유형 - 사용하는 프로그래밍 언어에 따라서 직접적으로 사용이 필요한 경우가 있다.
  • rows[] : 삽입할 데이터(행)들을 포함한다.
  • rows[].json :
  • json형태로 데이터를 입력 가능하다. key(스키마): value(입력 값)의 구조를 가지며, 대상 테이블의 스키마 구조에 대응되는 형태로 스키마와 값을 입력하여야 한다. 하나이상의 행에 대한 입력이 가능하다.

 

선택적(Optional) 속성
  • rows[].insertId : 앞서 설명한 데이터의 일관성을 보장하기 위한 옵션이다.
  • templateSuffix : 앞서 설명한 것처럼, String 타입의 값으로 사용자가 임의의 값을 설정하여 데이터 로딩을 실행하면 <대상 테이블> + <templateSuffix>형태로 새로운 테이블이 자동생성되고 해당 요청에 대한 데이터가 로딩된다.
  • skipInvalidRows : 적합하지 않은 행이 존재하더라도 모든 유효한 행의 데이터를 삽입한다. boolean형으로 기본값은 false이다.
  • ignoreUnknownValues: 테이블의 스키마와 일치하지 않는 유형의 값은 무시된다. boolean형으로 기본값은 false이다.

 

Response body구조

  • kind : 응답 자원 유형을 나타낸다. - 사용하는 프로그래밍 언어에 따라서 직접적으로 사용이 필요한 경우가 있다.
  • insertErrors[] : 실패한 요청의 경우 해당 오류에 대한 내용을 json배열형태로 반환한다.


※앞서 스트리밍 데이터 로딩을 위한 기초적인 내용을 설명하였으며, Node.js를 활용하여 실제로 스트리밍으로 데이터를 로딩하여 보도록 하자.


VM환경 준비하기

프로젝트 선택

기존의 프로젝트를 선택하거나,

 

또는 새로 생성하고 진행한다.

  

VM준비(VM 생성 or 기존의 VM사용)

스트리밍 API를 사용해서 데이터로딩을 하기위해서 리눅스 기반의 VM인스턴스를 준비한다. 

주의할 점으로 해당 VM은 앞서 설명한, tabledata().insertAll() 메소드를 접근해서 사용 할 수 있는 범위의 권한을 가지고 있어야 한다.

 

이글에서는 기존의 VM을 사용했으며, 테스트에 사용한 VM의 정보는 다음과 같다. 

  • Name : test
  • Boot disk : Ubuntu 14.04 LTS / SSD 10GB

*리눅스 기반의 각자가 사용하기 편리한 다른 OS이미지를 포함하여, disk의 용량이나 타입도 각자의 환경에 맞춰서 적용해도 상관없다.

  • Access scopes : Allow full access to all Cloud APIs

편의를 위해 구글 클라우드의 모든 서비스에 Access 가능한 범위를 지정하였다.

*앞서 언급한 tabledata().insertAll() 메소드를 사용할 수 있는 권한 범위를 적용하여야 한다.

  • 나머지는 기본값으로 설정


선택사항

  • Firewalls : Allow HTTP traffic, Allow HTTPS traffic 체크

이 글에서는 HTTP, HTTP(S)의 방화벽 규칙을 설정하고 진행한다.


*단순 스트리밍 로딩을 위해서는 따로 HTTP(S)트래픽을 허용하지 않아도 위의 다른 GCP서비스에 대한 접근 범위 설정을 통해 Streaming API에 사용에 대한 권한을 가지게 된다. 때문에 무리없이 실행은 가능하다. 하지만 실제 어플리케이션 구성에서는 구성환경에 맞춰서 HTTP, HTTP(S)에 대한 트래픽을 허용해기 위해 방화벽 규칙을 설정해야 될 것이다.

   

VM인스턴스 접근 범위 확인하기

Access scopes에 대한 적합한 설정이 되어있어야 한다는 것만 명심하자.

또한 Access scopes는 VM을 생성 할 때만 적용 가능하다.

  

VM 신규 생성 시 주의사항

Identity and API access에서 적합한 Access scopes를 설정하고 생성해야 한다.


BigQuery API 활성화

스트리밍 데이터 로딩을 실행하기 위해서는 BigQuery API를 활성화 해야 한다. 다음의 BigQuery API페이지로 이동한다.

https://console.developers.google.com/apis/api/bigquery

 

상단의 ENABLE를 클릭하여 BigQuery API를 활성화 한다.

만약, 이미 BigQuery API가 활성화 되어 있다면 다음 단계로 바로 이동한다.

 

Google Cloud SDK설치

기본적으로 구글 클라우드 SDK(command line interface) 가 설치되어 있다는 가정하에 진행한다. 

만약 설치가 안되어 있다면 다음의 주소를 참고하여 설치하도록 한다.

https://cloud.google.com/sdk

 

Auth 인증

다음으로 Default Credentials정보를 인증하기 위해 SSH터미널에 접속한다.

auth인증을 위해 다음 명령어를 실행한다.

%gcloud auth login

만약 위의 명령어로 진행이 되지 않는다면 아래 명령어를 입력하여 진행한다.

% gcloud auth application-default login 

위의 명령어를 입력하고 y를 입력하고 아래에 나타난 링크를 복사하여 브라우저에서 해당 링크로 접속한다.

해당 계정을 선택하면 다음과 같은 화면이 나타나고 허용을 클릭한다.

 

다음과 같이 인증코드가 생성된다.

 

 

인증코드를 복사하여 앞서 코드를 검증하는 부분에 붙여 넣고 엔터를 입력하면

Default Credentials 인증이 성공한 것을 확인할 수 있다.

 

Node.js 환경 준비하기

이번 예제에서는 기본적으로 node.js와 npm이 설치되어 있다고 가정하고 진행한다. 

이 글은 node.js 4.4.7버전과 npm 2.15.8버전을 기준으로 작성하였다.

또한 root계정으로 진행한다. 편의를 위해 express프로젝트로 진행한다.

 

Express generator 설치

Express generator설치를 통해서 기본적인 Express 프로젝트의 구조로 생성하기 위해 다음의 명령어를 실행한다.

% npm install express-generator -g

 

Express 프로젝트 생성

Express 프로젝트를 생성하기 위해 다음의 명령어를 실행한다.

% express --session --ejs --css stylus test

다음 명령어를 실행하여 프로젝트 생성을 마무리한다.

% cd test && npm install

 

Express 프로젝트 및 프레임워크에 대해서는 http://bcho.tistory.com/887

http://bcho.tistory.com/888 글을 참고하기 바란다.

 

Bigquery API Client Library 설치

구글 빅쿼리는 npm으로 node.js Library를 제공한다. 다음의 명령어를 실행해서 Bigquery API Client Library를 설치한다.

% npm install googleapis  --save

 

 

스트리밍 데이터 로딩하기

이제 스트리밍 데이터 로딩을 위한 준비는 완료되었다. Node.js와 스트리밍 API를 사용해서 데이터 로딩을 해보도록 한다.

 

Streaming API 기본 예제 - Node.js

vi등의 편집기를 이용해서 app.js파일을 열고 다음과 같은 내용을 추가한다.

var google = require('googleapis');
var bigquery = google.bigquery('v2');

google.auth.getApplicationDefault(function(err, authClient) {
  if (err) {
    console.log('Authentication failed because of ', err);
    return;
  }
  if (authClient.createScopedRequired && authClient.createScopedRequired()) {
    var scopes = ['https://www.googleapis.com/auth/cloud-platform'];
    authClient = authClient.createScoped(scopes);
  }

  var request = {
    // TODO: Change placeholders below to appropriate parameter values for

the 'insertAll' method:

    // Project ID of the destination table.
    projectId: "",
    // Dataset ID of the destination table.
    datasetId: "",
    // Table ID of the destination table.
    tableId: "",
    resource: {},
    // Auth client
    auth: authClient
  };

  bigquery.tabledata.insertAll(request, function(err, result) {
    if (err) {
      console.log(err);
    } else {
      console.log(result);
    }
  });
});


Node 예제 구성요소 안내

google.auth.getApplicationDefault() {}

앞서 Auth 인증한 Default Credentials 정보를 확인한다. 

var scopes = ['https://www.googleapis.com/auth/cloud-platform'];
위에
설명한 것처럼, 스트리밍 로딩을 위한 VM생성 시에 가지고 있는 접근 범위 에 따라서 적합한 범위의 URI가 입력되어야 한다.

https://www.googleapis.com/auth/cloud-platform 은 구글 클라우드 플랫폼의 모든 서비스에 대한 Full Access 범위를 나타난다.

var request 내부 내용을 살펴보면 기본적으로 확인 할 내용은 다음과 같다.

projectId: "",

""안에 해당하는 프로젝트 ID,

datasetId: "",

""안에 해당하는 데이터셋의 ID,

tableId: "",

""안에 해당하는 대상 테이블의 ID 

resource: {} 에서 중괄호 안에 위에서 설명한 기본 Request body의 형식에 맞게 실제 입력할 데이터의 내용을 입력한다.

bigquery.tabledata.insertAll() {}부분에서 데이터 로딩이 실행되는 부분으로, 만약 에러가 있다면 에러에 대한 내용을 반환한다.

 

스트리밍 로딩 테스트

이제 예제 코드에 대한 대략적인 구조를 파악하였다면 스트리밍 API를 사용해서 실제 테이블에 데이터를 입력해보자.

 

테이블 정보

테스트에 사용할 테이블은 앞서 구글 스토리지를 활용한 데이터 로딩에서 생성한 csv_test 테이블을 사용하도록 한다. 테이블 csv_test는 다음과 같은 스키마를 가지고 있다.

 

Node.js 코드 작성하기

  • projectId: “사용자의 프로젝트ID”
  • datastId: “데이터를 입력할 테이블을 가지고 있는 데이터셋ID”
  • tableId: “실제로 데이터를 로딩 할 테이블Id”
  • resource: { 입력 할 데이터 }

위에서 설명한 request body의 형식으로 대상 테이블의 스키마에 대응되는 적합한 값을 입력해야 한다. 입력을 완료하고 파일을 저장한다.

 

데이터 로딩 실행 

이제 앞서 작성한 내용의 데이터를 로딩하기 위해 다음 명령어를 실행해서 Node.js서버를 구동한다.

%npm start

해당 스트리밍 로딩 요청에 대한 tableDataInsertAllResponse로 응답이 완료됨을 확인할 수 있다. 응답이 완료된 것을 확인하고 ctrl+c를 입력하여 실행을 중지한다.

 

데이터 로딩 결과 확인하기

이제 빅쿼리 웹 콘솔(Web UI)로 이동해서 간단한 쿼리 실행을 통해 데이터가 정상적으로 입력되었는지 확인해보자.

  

쿼리 실행하기

좌측 상단의 COMPOSE QUERY 버튼을 클릭한다.

 

다음과 같이 쿼리를 입력하고 RUN QUERY 버튼을 클릭하여 쿼리를 실행한다.

SELECT word, word_count, corpus, corpus_date

FROM load_test.csv_test

WHERE word_count=1111

 

쿼리가 실행되었다. 앞서 입력한 데이터를 확인 할 수 있다.

 

템플릿 테이블을 이용한 테이블 자동생성

이제 앞서 설명한 templateSuffix속성을 활용해 csv_test 테이블을 템플릿으로 하여 같은 스키마를 가진 새로운 테이블을 생성해보자.

 

Node.js 코드 작성하기

vi편집기등으로 app.js파일을 열고 다음의 내용을 추가하고 파일을 저장한다.

  • templateSuffix: "String형의 임의의 값"

 

자동 테이블 생성 및 데이터 로딩 실행

템플릿 테이블을 활용해서 자동으로 새로운 테이블 생성 및 데이터로딩을 위해 node.js 서버를 실행한다.

%npm start

응답이 완료되었다. ctrl+c를 입력하여 실행을 중지한다.

 

자동 테이블 생성 및 데이터 로딩 결과 확인하기

이제 다시 빅쿼리 웹 콘솔로 이동해서 테이블이 자동으로 생성되고 입력한 데이터가 제대로 로딩되었는지 확인한다. (새로고침이 필요할 수 있다.)

 

먼저 자동 생성된 테이블 부터 확인한다. 앞서 설명한 것처럼 <대상 테이블> + <templateSuffix>의 형태로 csv_test1234라는 새로운 테이블이 생성되었다. 템플릿의 대상이 되는 테이블인 csv_test와 동일한 스키마를 가진다.

 

데이터 로딩 결과 확인하기 - 자동생성 테이블

이제 자동으로 생성된 테이블을 확인하였다면 해당 테이블에 스트리밍으로 입력한 데이터를 확인해보도록한다.

 

쿼리 실행하기

COMPOSE QURERY버튼을 클릭해서 다음과 같은 쿼리를 입력하고 RUN QUERY 버튼을 클릭하여 쿼리를 실행한다.

SELECT word, word_count, corpus, corpus_date

FROM load_test.csv_test1234

WHERE word_count=1111


쿼리가 실행되었다. 앞서 입력한 데이터를 확인 할 수 있다.

*날짜 단위 또는 각각의 사용자 단위 등으로 테이블을 분할하여 생성할 필요가 있을 때, 

templateSuffix의 값에 따라서 자동으로 테이블을 생성하여 데이터를 입력할 수 있기 때문에 매우 유용한 기능이다.

 

자동 테이블 생성 참고사항

templateSuffix속성을 활용해서 자동으로 테이블 생성하고 데이터를 입력한 경우에 빅쿼리 

웹콘솔에서 바로 Preview를 클릭하면 스트리밍 버퍼에서 데이터 로딩을 통해 입력한 데이터를 

가지고 있어서 입력한 값이 바로 나타나지 않을 수 있다.

*스트리밍 데이터 입력에 수초가 소요될 수 있으며, 입력된 데이터를 복사하고, 

내보내기에 사용 될 수 있기까지 90분까지 소요 될 수 있다

 

 

데이터 일관성 확인

앞서 insertId를 통해 데이터의 일관성을 보장해주는 부분에 설명하였다. 이제 실제로 insertId를 사용해 데이터가 어떻게 변화하는지 확인해본다.

 

Node.js 코드 작성하기

vi등의 편집기를 이용해서 app.js파일을 열고 다음의 내용을 추가하고, 입력할 데이터의 내용을 수정한다.

  • insertId: "String형의 임의의 값"

입력 데이터의 경우 앞서 테스트한 결과와 구분을 위해 다른 값으로 변경한다.

   

데이터 로딩 실행 - insertId

insertId가 적용된 데이터로딩을 하기 위해서 node.js서버를 실행한다.

%npm start

응답이 완료되었으면 빅쿼리 웹 콘솔로 이동해서 입력된 데이터를 확인한다.

 

데이터 로딩 결과 확인하기 - insertId

빅쿼리 웹 콘솔에서 COMPOSE QUERY를 클릭하고 다음의 쿼리를 입력한다.

SELECT word, word_count, corpus, corpus_date

FROM load_test.csv_test1234

WHERE word_count=2222

RUN QUERY를 클릭하여 쿼리를 실행하고 입력된 데이터를 확인한다.

쿼리 수행결과를 통해, 정상적으로 입력된 데이터를 확인 할 수 있다.

 

데이터 중복 입력 확인하기

다시 SSH터미널에서 ctrl+c를 입력하여 서버 실행을 중지하고 app.js의 내용을 변경하지 않고, 다시 한번 node.js서버를 실행한다.

 

데이터 중복 확인 - 쿼리 테스트

빅쿼리 웹 콘솔로 이동해서 위와 동일한 쿼리를 실행해서 결과를 확인한다.

 

쿼리를 실행하면 앞서 입력한 데이터(행)만 나타난다. 같은 insertId를 가지고 있기 때문에 중복된 데이터가 추가로 입력되지 않는다.

 

*insertId가 없는 경우, 스트리밍 로딩을 할 때 데이터의 중복에 관계없이 새로운 데이터(행)가 추가된다. 각각 테스트해보길 권장한다.

   

데이터 변경하기 - Node.js 코드 수정하기

SSH 터미널에서 node.js서버를 중지하고 vi등의 편집기로 app.js파일을 열고 데이터의 내용을 변경하고 저장한다.

 

데이터 변경 후 로딩 실행 - insertId

앞서 같은 insertId를 가진 상태에서 변경한 데이터를 로딩하기 위해 다음 명령어를 실행해서 node.js서버를 구동한다.

%npm start

응답을 확인하고 웹 콘솔로 이동해서 입력된 데이터를 확인해보자.

 

데이터 변경 입력 후, 로딩 결과 확인하기

기존에 데이터가 어떻게 변화하였는 지 확인하기 위해 빅쿼리 웹 콘솔에서 앞서 실행한 쿼리를 입력하고 결과를 확인한다.

SELECT word, word_count, corpus, corpus_date

FROM load_test.csv_test1234

WHERE word_count=2222 

앞서 위의 쿼리 실행을 통해 데이터가 로딩된 결과를 확인했었다. 하지만 해당 쿼리가 

실행되면 조회되는 데이터가 없음을 확인 할 수 있다

 

이번에는 변경한 데이터의 word_count값인 3333으로 WHERE 조건을 변경하고 쿼리를 실행해보자

SELECT word, word_count, corpus, corpus_date

FROM load_test.csv_test1234

WHERE word_count=3333

변경해서 입력한 데이터에 대한 조회결과가 나타난다. 이와 같이 같은 행에 대한 insertId가 적용된 상태에서 데이터가 변경되어 다시 입력되는 경우, 기존의 입력된 데이터는 변경된다.

 

*insertId의 경우 데이터의 일관성을 확인하고 보장하기 위해 좋은 수단이 될 수 있으나, 앞서 언급한 것처럼 1분정도만 보장되는 시간적인 제약이 있으니 참고하기 바란다.

 

결론

빅쿼리의 스트리밍 데이터 로딩의 경우, 몇가지 제약적인 부분은 있지만, 실시간으로 대량의 이벤트 로그 분석, 실시간으로 데이터와 연동하는 dashboard등에 활용하기 좋다. 또한 빅쿼리의 대용량의 데이터 분석 뿐만 아니라 실시간의 데이터 로딩, 분석을 융합적으로 활용하면, 급변하는 시장에서 빠르게 대응 할 수 있는 또 하나의 대안이나 수단으로 이용할 수 있을 것이다.

 

참고자료

https://cloud.google.com/bigquery/streaming-data-into-bigquery

https://cloud.google.com/bigquery/docs/reference/v2/tabledata/insertAll

https://cloud.google.com/bigquery/quota-policy#streaminginserts

구글 클라우드 사용팁

최유석

 

Compute Engine

여러 VM인스턴스에서 디스크 공유 하기

VM인스턴스들은 read-only(읽기전용) mode로 성능하락 없이 디스크를 공유할 수 있다.

read-write(읽기-쓰기) mode에서는 하나의 VM인스턴스에서만 해당 디스크를 사용할 수 있다.

 

디스크 공유하기

1.VM 상세 페이지에서 Edit를 클릭하고 Boot disk and local disk탭에서 Additional disks부분의

+Add item을 클릭한다.

 

2. Mode를  Read only로 변경하고 Name에서 Create disk를 클릭하여 디스크를 생성한다.

적당한 디스크 이름(test-disk)을 입력하고 Source type탭에서 None(blank disk)를 지정하고 

생성하기를 원하는 Size를 입력하고 Create버튼을 클릭하여 디스크를 생성한다.

 

 

*기존에 생성했던 디스크가 있다면 해당 디스크를 사용 할 수 있다. 

추가적인 disk가 없기에 새로 생성하는 방법으로 진행한다.

 

3. VM인스턴스 상세페이지에서 Save를 클릭하여 적용한다.

 

4. 읽기전용 disk를 공유하기 위해 다른 VM의 상세 페이지에서 Edit를 

클릭하고 디스크 탭으로 이동한다. 위와 마찬가지로 +Add item을 클릭한다.

5. 앞서 다른 VM에서 생성한 disk를 Name을 클릭하면 선택 할 수 있으며, 

해당 disk를 선택하고 Mode를 Read only로 지정한 후 페이지 하단의 Save를

 클릭하여 해당 내용을 저장한다.

6. 디스크 공유가 완료되었다. 디스크를 생성해서 연결한 VM과 뒤에 추가로 

같은 disk를 연결한 VM의 상세페이지에서 각각 읽기전용으로 디스크가 공유된 것을 확인 할 수 있다.

 

  • 디스크를 생성하고 연결한 VM

  • 추가적으로 디스크를 공유한 VM

같은 방법으로 다른 VM에도 추가적으로 디스크 연결이 가능하다.

 

* 주의할 점은 하나의 디스크로 각각 다른 VM에 읽기전용, 읽기/쓰기 동시 지원이 안되니 참고바란다. 

오직 디스크가 읽기전용에서만 여러 VM인스턴스에서 공유 가능하다.

* 하나의 VM에 연결 된 디스크는 읽기전용, 읽기/쓰기 모드의 상호변경이 가능하다.

 

디스크 공유하기 참고페이지

https://cloud.google.com/compute/docs/disks/add-persistent-disk

 

구글 클라우드 시작하기

구글 빅쿼리 데이터 로딩하기

 최유석

개요

구글의 대용량 데이터 분석 서비스인 빅쿼리에 구글 클라우드 스토리지를 활용하여 CSV, JSON형식의 데이터를 로드하고 테이블을 생성하는 방법에 대해서 알아보도록 한다.

 

또한,빅쿼리에서는 데이터 파일의 단일 업로드뿐만 아니라 병렬 업로드(다중파일 동시 업로드)도 제공한다.따라서, 이번 글의 뒤쪽에서는 단일CSV파일로 데이터로딩을 해보고, 그 CSV파일을 여러 개의 파일로 분할하여 병렬로 데이터를 로드해서 각각의 처리 속도를 확인해본다.

그리고 CSV 병렬 업로드를 위해 분할한 데이터를 이용하여 JSON, Avro포맷으로 변환하여 각각의 형식에 따라 동일데이터라도 데이터 로딩시간이 어떻게 달라지는지 확인해보도록 하자

 

구글 클라우드 스토리지(Google Cloud Storage : GCS)

구글 클라우드 스토리지는 구글 클라우드 플랫폼에서 지원하는 BLOB(Binary large object) Store로 구글 클라우드 플랫폼의 모든 서비스들과 연계하여 사용이 가능하다.구글 클라우드 플랫폼에서 제공하는 파일,미디어 등의 저장에 특화된 서비스이다.

 

GCS 스토리지 클래스

Standard:

높은 data availability(99.9%)와low latency을 가지고 있어서 데이터에 대한 빠른 응답속도(ms)를 보인다.따라서 데이터에 대한 빠른 접근,빈번한 접근이 필요한 경우에 사용하기 적합하다.활용하기 적합한 예로는 웹사이트 컨텐츠,모바일 또는 게임 어플리케이션, 등이 있다.

   

Durable Reduced Availability (DRA) :

Standard에 비해 약간 낮은 가격과 data availability(99%)를 가지고 있다.

데이터 백업,배치(batch) 작업에 사용하기 적합한 클래스이다.

 

Nearline : data archiving 이나 online backup, 재해복구(disaster recovery)용도로 사용하기 적합한 클래스로 가장 저렴한 비용으로 이용할 수 있다. 데이터 접근에 시간단위가 소요되는AWS의 glacier서비스등에 비해서 매우 빠른 속도로 초 단위(대략3초)로 다른 클라우드 업체들의 유사서비스들에 비해서 매우 높은 성능을 가진다.

 

*구글 클라우드 스토리지 클래스 모두 동일한 API를 사용하고 AWS의 S3와 API호환되서 API사용에 대한 부담이 적다.

 

GCS 기본 구성요소

프로젝트(Project) :

최상위 컨테이너로 구글 클라우드 스토리지의 모든 자원(resources)은 프로젝트 위에서 생성되고 관리된다. 또한 스토리지 자원들에 대하여 권한제어가 가능하다.

 

버켓(Bucket) :

데이터 또는 파일을 저장하고 관리하기 위한 컨테이너이다.구글 클라우드 스토리지에서의 최소단위인 Object(각각의 데이터 또는 파일단위)가 저장되는 공간이며, 버켓 생성 시에 앞서 설명한 클래스와 데이터가 저장될 위치를 지정하여야 하고 생성 후에는 변경이 불가능하다.새로 생성하거나 다른 버켓으로 이동시키는 등의 방법을 사용하여야 한다.

  

오브젝트(Object) :

실제로 구글 클라우드 스토리지에 저장되는 각각의 데이터 또는 파일을 의미한다. 하나의 오브젝트는 최대 5TB까지 저장할 수 있다.

 

빅쿼리 기본구조

*빅쿼리에 대한 개념, 아키텍쳐 등의 기본적인 이해가 필요하다면 아래 주소의 정보를 참고하기 바란다.

http://bcho.tistory.com/category/%EB%B9%85%EB%8D%B0%EC%9D%B4%ED%83%80/Google%20BigQuery

   

프로젝트(Project)

빅쿼리에서 프로젝트는 하위 구조인 데이터셋을 가질 수 있으며,하나의 프로젝트 안에는 다수의 데이터셋을 가질 수 있다. 또한 사용자와 데이터셋에 대한 권한 제어를 포함한 전반적인 리소스의 관리를 담당한다.

 

데이터셋(Dataset)

하나 이상의 테이블을 가질 수 있는 테이블에 대한 집합으로 테이블을 관리한다. 빅쿼리에서 권한제어를 할 수 있는 최소 단위로 데이터셋에 대한 권한부여를 통해 다른 사용자와 데이터를 공유 할 수 있다. (MySQL의 database와 비슷한 개념이다.)

 

테이블(Table)

실제 데이터가 저장되는 테이블이다. 스키마를 가지고 있으며 행(row)단위 업데이트는 지원되지 않는다.테이블에 대한 권한제어는 따로 적용되지 않으며 해당 테이블을 가지고 있는 부모 데이터 셋으로부터 상속받는다.

 

잡(Job)

잡은 쿼리, 데이터 로딩, 삭제, 복사, 내보내기 등의 명령을 수행하는 비동기식 연산으로 4가지 구성요소를 가지고 있다.

 

잡(Job)의 구성요소

○ Reference - job ID : 유니크 한 이름

○ Configuration - job task : 수행하는 작업의 종류

○ Status - job state : 오류와 경고를 포함한 상태

○ Statistics - job statistics : 수행내역을 제공하는 통계

 

잡의 구성요소들은 향후 감사(Audit)등의 목적을 위해서 로그를 남기게 된다. 또한 잡은 실행 도중 취소가 가능하다. 하지만 취소하였다 하더라도 해당 명령에 대한 프로세싱은 이루어지기 때문에 비용이 발생한다.

 

데이터 타입

  • STRING : UTF-8인코딩. 최대 2MB
  • BYTES : base64로 인코딩 된 이진 데이터
  • INTEGER : 64 bit signed integer
  • FLOAT : Double precision, floating-point format
  • BOOLEAN : CSV format: true or false (case insensitive), or 1 or 0

                                      JSON format: true or false (case insensitive)

  • RECORD : A Collection of one or more field
  • TIMESTAMP

 

*데이터 타입 중 RECORD의 경우 중첩 및 반복을 허용하고 JSON과 같이 여러 개의 데이터 값을 가질 수 있다. 불필요한 반복 및 중첩이 많아지면 쿼리를 포함한 여러 가지 작업들이 어려워지니 가급적 피하는 게 좋다.

 

데이터 필드의 모드

  • REQUIRED : NULL값을 허용하지 않음
  • NULLABLE : NULL값을 허용(기본값)
  • REPEATED : NULL값을 허용하고 1개 또는 배열 형태로 여러 개의 값을 가질 수 있으며 JSON, Avro포맷에서만 사용가능하다.

 

데이터 로딩 포맷

  • CSV
  • JSON(newline-delimited)
  • Avro
  • Cloud Datastore backups
  • Google sheets

*스키마에 따라서 CSV, JSON, Avro 모두 flat data를 지원하지만, 스키마에 중첩되거나 반복되는 필드를 가진 경우 JSON, Avro만 지원한다.

*기본적으로 데이터에 줄바꿈(개행문자)이 포함되어 있는 경우 JSON, Avro가 빠르다.

 

데이터 로딩 지원도구(Tools)

  • Web UI : 웹 브라우저 기반으로 제공하는 빅쿼리 전용 웹 콘솔로 비전문가도 사용하기 쉽다.
  • Command-line interface (CLI) : 파이썬 기반의 명령어 도구가 제공된다.
  • REST API (POST) : POST요청으로 데이터 로딩을 할 수 있는 REST형태의 API를 제공하며, 재개 가능(Resumable)업로드, 다중 부분(Multipart) 업로드의 두가지 옵션을 제공한다.
  • Streaming API : 잡을 사용해서 대규모의 데이터를 로드하는 대신 한번에 하나의 레코드를 삽입할 수 있는 API를 제공한다.
  • Third-party ETL tools and connectors : 각종 3party의 ETL(Extract, Transform, Load) 툴 및 시각화, 개발환경 등과의 연동할 수 있도록 커넥터를 제공한다.

 

데이터 로딩(Load job)제한

 

*하루 기준으로 실패를 포함하여 최대 테이블 당 1,000개, 프로젝트 당 10,000개의 잡을 처리할 수 있다.

 

최대 행(row) 또는 cell 크기(데이터 포맷에 따라 구분)

Data Format Max limit
CSV 2 MB (row and cell size)
JSON 2 MB (row size)
Avro 16 MB (block size)

 

*하나의 테이블 당 최대 10,000개의컬럼(columns)까지 생성 할 수 있다.

 

데이터 파일 최대크기 (데이터 포맷에 따라 구분)

File Type Compressed Uncompressed
CSV 4 GB • With quoted new-lines in values: 4 GB
• Without new-lines in values: 5 TB
JSON 4 GB 5 TB
Avro Compressed Avro files are not supported, but compressed data blocks are. BigQuery supports the DEFLATE codec. 5 TB (2 MB for the file header)

 * Avro포맷의 경우 파일에 대한 압축은 지원되지 않음

* 데이터 로딩동시 업로드 파일은 최대 10,000개까지 지원한다.

 

구글 클라우드 스토리지를 활용하여 CSV, JSON 형식의 데이터 로딩하기

 

프로젝트지정

기존의 프로젝트를 선택하여 진행하거나

 

새로 생성해서 진행한다.

 

 

 

구글 클라우드 스토리지에 데이터 업로드하기

구글 클라우드 스토리지에서 CSV, JSON파일을 업로드하여 사용하기 위해 좌측상단 탭의 스토리지 메뉴로 이동한다.

 

 

버켓(bucket)생성하기

 

  • Name : load-bigquery (임의의 값)
  • Storage class : Standard (각자의 프로젝트 환경에 적용할 클래스를 선택한다.)
  • Location : Asia (원하는 지역을 선택해도 무방하다.)

 

CSV, JSON파일 업로드

본 예제에서는 다음의 파일들을 이용한다. 서로 동일한 테이블 데이터를 가지고 있다.

  • CSV   : shakespeare.csv
  • JSON : shakespeare.json

상당의 UPLOAD FILES를 클릭 후 파일을 선택하고 업로드를 진행한다.

 

업로드가 완료되었다.

   

이제 빅쿼리로 이동해서 앞서 구글 클라우드 스토리지에 업로드한 CSV, JSON형식의 데이터를 사용해서 테이블을 생성하고 데이터를 로드해보자

 

데이터 로딩하기

구글 클라우드 콘솔의 좌측 상단 탭을 클릭하여 빅쿼리 웹 UI로 이동한다.

  

데이터셋(dataset)생성하기

프로젝트명 오른쪽에 있는 화살표 박스를 클릭하여 데이터셋을 생성한다

 

데이터셋에 생성 할 ID를 입력하고 나머지는 기본값으로 데이터셋을 생성한다

 

  • Dataset ID : load_test (임의의 값)
  • Data location : unspecified (unspecified, US, EU)
  • Data expiration : Never (영구히 저장하거나 또는 만료기간 지정가능 – 자동 삭제됨)

 

*Data location은 데이터셋이 가지고 있는 테이블을 포함하여 데이터가 실제로 위치할 위치를 지정할 수 있다. 제공되는 옵션으로는 지정하지않거나, 미국, 유럽을 선택할 수 있다.

 

Dataset이 생성되었다. 앞서 임의로 생성한 데이터셋 load_test 위에 테이블을 생성해보자.

   

테이블 생성하기 - CSV

구글 클라우드 스토리지에 저장한 CSV 파일을 이용해서 데이터를 로딩하여 테이블을 생성해보자

 

먼저 데이터셋 우측의 +모양의 버튼을 클릭하여 테이블 생성 메뉴를 불러온다

   

CSV포맷의 데이터를 로드하고 테이블을 생성하기 위해 내용을 입력하고 필요한 옵션을 설정하여 테이블을 생성한다..

 

Source Data

Location : Google Cloud Storage - gs://load-bigquery/shakespeare.csv

데이터를 가져올 위치로 앞서 구글 클라우드 스토리지에 저장한 CSV파일의 URI를 입력한다

 

*구글 클라우드 스토리지 URI 형식 : gs://<bucket>/<object>

* Location의 다른 옵션

  • File Upload : 로컬 파일을 업로드하여 사용할 수 있다.
  • Google Drive : 구글드라이브에 저장된 파일을 공유한 링크를 이용할 수 있다.
  • None(create empty table) : 스카마만 구성하여 빈 테이블을 생성할 수 있다.

 

File format : CSV

Location에서 none(빈테이블 생성)을 제외한 모든 옵션에서 CSV, JSON, Avro포맷을 사용 할 수 있다.

 

*특수한 경우로 각각의 위치에 따라서 추가적으로 지원되는 포맷이 다르다.

구글 클라우드 스토리지: Google Cloud Datastore backup files

구글 드라이브: Google Sheets

 

Destination Table

Table name : load_test . csv_test

Destination Table은 앞서 생성한 데이터셋인 load_test를 지정하고 뒤에 생성 할 테이블 이름을 입력한다.

*테이블의 경우 ( . ) 으로 구분하여 <project id>:<dataset id>.<table name> 형태로 쿼리에 사용할 수 있다. 프로젝트 ID의 경우 해당 프로젝트에서 작업하는 경우 생략 가능하다.

 

Table type : Native table

빅쿼리 내부 스토리지에 저장되는 테이블)

Table type 추가옵션 : External table

빅쿼리 내부 스토리지가 아닌 구글 클라우드 스토리지나 구글 드라이브에 저장되는 테이블로 빠른 생성 및 수정이 가능하지만, 빅쿼리의 쿼리성능을 높이는 컬럼 기반 구조를 사용할 수 없게 되어 성능저하가 발생한다.

 

Schema

Edit as Text를 클릭하고 다음과 같이 "name:type" 형태(CSV기준)로 입력하거나,

 

word:STRING, word_count:INTEGER, corpus:STRING, corpus_date:INTEGER 

 

또는 Add Field를 클릭하여 각각 필드를 추가하여 Name을 입력하고 Type을 지정한다.

 

Field delimiter:Comma ( 구분자로 사용할 요소를 선택 )

Header rows to skip : 1 (최상단의 행부터 행단위로 데이터를 스킵하고 해당 예제에서는 상단에 스키마 정보가 있는 상태라서 1행을 스킵하고 진행한다.)

*데이터만 입력하는 경우 기본값인 0으로 입력한다.

테이블을 생성 시에 기본적으로 고려해야할 사항들에 대해서 언급하였으며,나머지는 기본값으로 입력하고 Create Table을 클릭하여 생성한다.

 

테이블이 생성되었다.

 

테이블 테스트 - CSV

좌측상단의 COMPOSE QUERY를 클릭하여 테이블이 정상적으로 생성되었는지 간단한 쿼리를 실행해서 테스트해보자.

 

다음은 테이블의 모든 데이터를 읽어와10개값만 보여주는 SELECT쿼리이다.

 

SELECT word, word_count, corpus, corpus_date 

 

 

FROM load_test.csv_test 

 

 

ORDER BY word_count DESC LIMIT 10 

 

 

RUN QUERY버튼을 클릭하여 쿼리를 실행한다.

   

테스트로 입력한 쿼리가 정상적으로 실행되었다.

 

다음으로는 JSON형식의 데이터 파일을 로드 하여 테이블을 생성해보자.

 

데이터 로딩하기 - JSON

데이터셋(load_test)의 우측 + 버튼을 클릭하여 테이블을 생성한다.

 

JSON포맷의 데이터를 로드하고 테이블을 생성하기 위해 내용을 입력하고 필요한 옵션을 설정하여 테이블을 생성한다. .

 

Source Data

Location : gs://load-bigquery/shakespeare.json

JSON 파일도 마찬가지로 구글 클라우드 스토리지의 JSON파일 URI를 입력한다

File format : JSON(Newline Delimited)

 

Destination Table

Table name : json_test(임의의 값)

 

Schema

Edit as Text에 다음과 같이 텍스트로 JSON형태의 스키마를 입력한다.

 

[ 

 

 

    { 

 

 

        "name": "word", 

 

 

        "type": "STRING", 

 

 

        "mode": "REQUIRED" 

 

 

    }, 

 

 

    { 

 

 

        "name": "word_count", 

 

 

        "type": "INTEGER", 

 

 

        "mode": "REQUIRED" 

 

 

    }, 

 

 

    { 

 

 

        "name": "corpus", 

 

 

        "type": "STRING", 

 

 

        "mode": "REQUIRED" 

 

 

    }, 

 

 

    { 

 

 

        "name": "corpus_date", 

 

 

        "type": "INTEGER", 

 

 

        "mode": "REQUIRED" 

 

 

    } 

 

 

] 

 

*Add Field로 각각 생성해도 상관없다.각각의 환경에 따라서 사용하기 편한 방식으로 이용하도록 하자.

다음과 같이 스키마 정보가 정상적으로 입력된 것을 확인 할 수 있다.

 

이제 나머지 값은 기본값으로 하여 Create Table 버튼을 클릭하여 테이블을 생성해보자.

 

JSON포맷의 데이터로 생성한 테이블이 생성되었다.

 

테이블 테스트 – JSON

COMPOSE QUERY를 클릭하여 CSV로 입력한 데이터와 같은 데이터를 가지고 있기 때문에, 앞에서 CSV를 테스트한 쿼리를 이용하여 테스트해보자. 

 

SELECT word, word_count, corpus, corpus_date  

 

 

FROM load_test.json_test  

 

 

ORDER BY word_count DESC LIMIT 10 

 

 

RUN QUERY버튼을 클릭하여 쿼리를 실행해보자

 

테스트로 입력한 쿼리가 정상적으로 실행되었다.

 

*구글 클라우드 스토리지를 이용하여 데이터 교환의 표준 포맷이라고 할 수 있는 CSV, JSON형식의 데이터를 이용해 테이블을 생성하고 데이터를 로드하였다. 위의 예제에서는 데이터를 로딩하는 방법에 대한 설명하기 위해 작은 용량의 데이터를 가지고 진행하였다.하지만 빅쿼리는 기본적으로 대용량의 데이터를 실시간에 가까운 속도로 처리하고 분석하기 위해 설계되었고,GB,TB급의 데이터라도 매우 빠른 속도로 로딩이 가능하다. 따라서 위의 예제의 데이터보다는 비교적 큰 데이터를 이용해 앞서 언급한 단일, 병렬, 포맷에 따른 데이터 로딩시간을 확인해보도록 한다

 

업로드 속도 비교하기

시작하기전에 먼저 각각의 방식에서 속도(성능)를 확인하는 것이 주요 목적으로

각각의 업로드 방법에 대한상세한 설명은 생략한다.

 

기본 준비사항

원본 데이터

아래는 원본 테이블의 정보이다. 2014년의 항공편에 대한 데이터를 가지고 있으며 용량은 1GB가 약간 넘으며, 6,303,310개의 행(Rows)으로 이루어져 있다.

bq 명령어 도구

앞서 언급한 Command-line interface로 제공되는 도구이다. 파이썬 기반의 도구로 Google Cloud SDK에 포함되어 있으며, 기타 SSH를 사용하는 경우 따로 설치도 가능하다. 이후 진행 할 단일/병렬 업로드에 bq도구를 활용하도록 하겠다.

 

VM인스턴스 준비

테스트를 위해 Google Compute Engine의 VM인스턴스를 하나 생성하거나 기존의 VM인스턴스를 사용한다.

테스트에 사용한 VM은

  • machine type : n1-standard-1 (1 vCPU, 3.75 GB memory)
  • zone : asia-east1-b
  • disk : 10GB SSD
  • OS : ubuntu-1404-trusty-v20160627
  • 나머지는 기본값으로 설정

 

VM이 생성되면 이후 테스트를 진행하기 위해bq도구를 사용하기 위해 SSH에 접속한다.

 

CSV 단일 파일 업로드

데이터 준비

미리 구글 클라우드 스토리지에 데이터파일을 저장한다.

하나의 CSV 데이터파일과 해당파일을 6개의 파일로 분할한 파일들이다.

 

다음 명령어를 통해 CSV데이터의 업로드를 실행한다.

 

bq load --skip_leading_rows=1 \ 

 

 

--source_format=CSV bigquery-1369:load_test.flight_csv_single \ 

 

 

gs://load-bigquery/csv/flight.csv \ 

 

 

./schema_flight_performance.json 

 

  • bq : bq를 쓰기위한 명령어
  • load : 데이터 로딩을 위한 명령어
  • --skip_leading_rows=1 : 웹 UI의 Header rows to skip 옵션과 동일
  • --source_format=CSV : 포맷 지정
  • bigquery-1369:load_test.flight_csv_single :  

                생성 할 테이블 위치 <project id>:<dataset id>.<table name

               형태로 테이블을 지정한다.(웹 UI의 Table name과 동일)

  • gs://load-bigquery/csv/flight.csv :

                가져올 데이터 위치(웹 UI의 구글 클라우드 

                스토리지 URI와 동일)

  • ./schema_flight_performance.json : 사용할 스키마 내용 또는 파일

 

테이블이 생성 되었다.

 

웹 콘솔의 job History를 통해데이터 로딩에 소요된 시간을 확인해보자.

 

해당 잡의 시작시간과 종료시간을 보면CSV 단일 데이터 로딩에 46초가 소요된 걸 확인할 수 있다. (여러 번 테스트 해본 결과 테스트 결과 40초 ~ 60초 정도 소요됨)

 

다음 bq명령어로도 확인 가능하다

 

bq ls -j 

 

 

CSV 병렬 업로드

빅쿼리에서는 제공 하는 와일드카드 "*"로 동일 패턴의 String을 가진 여러 파일에 대한 동시 업로드를 사용할 수 있으며,

['gs://my-bucket/file-name-*.json']형태로 사용할 수 있다.

 

다음 명령어를 통해CSV데이터의 병렬 업로드를 실행한다.

 

bq load --skip_leading_rows=1 \ 

 

 

--source_format=CSV bigquery-1369:load_test.flight_csv_multi \ 

 

 

gs://load-bigquery/csv/flight0*.csv \ 

 

 

./schema_flight_performance.json 

 

생성한 테이블 명 : flight_csv_multi

가져올 데이터 위치(와일드카드 사용) : 

gs://load-bigquery/csv/flight0*.csv

 

테이블이 생성되었다.

 

웹 콘솔의 job History를 통해 데이터 로딩에 소요된 시간을 확인해보자.

해당 CSV 병렬데이터 로딩에 37초가 소요된 걸 확인할 수 있다.

(여러 번 테스트 해본 결과 테스트 결과 36초 ~ 50초 정도 소요됨)

 

*단일 업로드에 46초, 병렬 업로드에 37초가 소요되었다.9초의 차이가 발생한다. 당연한 결과지만 병렬 업로드가 더 빠르다.따라서 이 뒤의 JSON, Avro

포맷의 단일파일 업로드는 제외하고 진행한다.

 

JSON병렬 업로드

앞서 CSV병렬 업로드에 사용한 6개의 파일을 JSON으로 변환하고 변환된 파일들을 이용하여 병렬 업로드를 실행하고 속도를 확인해보자. 변환과정은 생략한다.

   

데이터 준비

CSV -> JSON으로 변환한 파일을 구글 클라우드 스토리지에 저장한다.

CSV와 비교했을 때 데이터 파일의 크기가 확연하게 커졌다. 차이가 발생하는 이유는 JSON의 경우 구조상 모든 데이터가 스키마를 포함하게 되어 데이터를 포함한 JSON파일의 크기가 커지게 된다.

 

 

다음 명령어를 통해 JSON포맷의 병렬 업로드를 실행한다.

 

bq load --source_format=NEWLINE_DELIMITED_JSON \ 

 

 

bigquery-1369:load_test.flight_json_Multi \ 

 

 

gs://load-bigquery/json/flight*.json \ 

 

 

./schema_flight_performance.json 

 

--source_format=NEWLINE_DELIMITED_JSON : JSON 포맷으로 지정한다.

 

테이블이 생성 되었다.

 

웹 콘솔의 job History를 통해 데이터 로딩에 소요된 시간을 확인해보자.

JSON포맷의병렬 데이터 로딩에 28초가 소요된 걸 확인할 수 있다.

(여러 번 테스트 해본 결과 20초 ~ 30초 정도 소요됨)

 

*CSV와 비교했을 때 JSON이 더 빠른 데이터로딩 속도를 보인다.

 

Avro 병렬 업로드

마지막으로 JSON과 동일한 방법으로 CSV병렬 업로드에 사용한 6개의 파일을 Avro포맷으로 변환하여 병렬 업로드를 하여 속도를 확인해보자. 변환과정은 생략한다.

 

데이터 준비

CSV -> Avro으로 변환한 파일을 구글 클라우드 스토리지에 저장한다.

같은 데이터를 가지고 있지만 CSV, JSON포맷과 비교했을 때데이터 파일의 크기가 작다.

 

다음 명령어를 통해 Avro포맷의 병렬 업로드를 실행한다.

 

bq load --source_format=AVRO \ 

 

 

bigquery-1369:load_test.flight_avro_Multi \  

 

 

gs://load-bigquery/avro/flight*.avro 

 

--source_format=AVRO : Avro포맷으로 지정한다

Avro의 경우 데이터파일에서 스키마의 정보를 포함하고 있기에 스키마를 따로 지정하지 않아도 된다.

 

테이블이 생성 되었다

 

웹 콘솔의 job History를 통해 데이터 로딩에 소요된 시간을 확인해보자.

Avro포맷의병렬 데이터 로딩에 40초가 소요된 걸 확인할 수 있다. 

(여러 번 테스트 해본 결과 35 ~ 45초 정도 소요됨)

 

*여러 번 테스트 한 결과 CSV 병렬 업로드 보다 빠르고 JSON보다는 느리다.

 

데이터 로딩 결과(시간)

  CSV(단일) CSV(다중) JSON(다중) Avro(다중)
업로드 시간 40초 ~ 60초 36초 ~ 50초 20초 ~ 30초 35 ~ 45초

 

결론

빅쿼리가 지원하는 데이터 포맷(CSV,JSON, Avro)을 이용해동일한 데이터에 대해서단일 파일 데이터 로딩을 포함하여, 단일 데이터파일을 분할하여 여러 개로 나눠서 병렬(다중파일 동시 업로드)데이터 로딩을 테스트하였다.다음과 같은 결과를 확인할 수 있었다.

  • 로딩 속도는 CSV > Avro > JSON

 

  • 데이터의 크기(비용적인 측면)는 Avro < CSV < JSON

 

물론 데이터의 크기가 더 커진다면 결과가 달라 질 수도 있겠지만, 위에서 테스트한 정보를 토대로 이야기하면 1GB의 용량에 6백만 행을 가진 데이터가 작지 않은 데이터라고 볼 수 있으나, 현재와 같이 빅데이터가 일반화 되어가는 시기에 수십,수백GB에서 TB까지(또는 그 이상)의데이터의 로딩의 여러가지 측면(비용,속도)을 생각하면, Avro포맷을 고려해 보는 것도 좋은 선택이 될 수 있을 것이다.

   

참고자료

https://cloud.google.com/bigquery/docs/

https://cloud.google.com/bigquery/loading-data

https://cloud.google.com/bigquery/docs/loading-data-cloud-storage

https://cloud.google.com/bigquery/data-types

https://cloud.google.com/bigquery/data-formats

https://cloud.google.com/bigquery/bq-command-line-tool

 

+ Recent posts