big query at gdg korea cloud meetup
TRANSCRIPT
BigQuery with AppEngine
LezhinEntertainment GDG Korea Cloud
judeKim
2015-01-27
Speaker
• - 레진엔터테인먼트 서버개발자
• - GDG Korea Cloud 운영자
• - Facebook Korea Docker User Group 운영자
about BigQuery?
BigQuery?
• Big Data를 실시간으로 분석할 수 있는 플랫폼
• Google I/O 2010 발표
Goal of BigQuery in Google I/O 2012
• Perform a 1TB table scan in 1 second Parallelize Parallelize Parallelize!
• Reading 1 TB / second from disk - 10k+ disks
• Processing 1TB / sec - 5k processors
Goal of BigQuery in Google I/O 2012
• Perform a 1TB table scan in 1 second Parallelize Parallelize Parallelize!
• Reading 1 TB / second from disk - 10k+ disks
• Processing 1TB / sec - 5k processors
Goal of BigQuery in Google I/O 2012
• Perform a 1TB table scan in 1 second Parallelize Parallelize Parallelize!
• Reading 1 TB / second from disk - 10k+ disks
• Processing 1TB / sec - 5k processors
Goal of BigQuery in Google I/O 2012
• Perform a 1TB table scan in 1 second Parallelize Parallelize Parallelize!
• Reading 1 TB / second from disk - 10k+ disks
• Processing 1TB / sec - 5k processors
BigQuery from Dremel
• BigQuery as a publicly available service for any business or developer to use
• REST API
• CLI ( command line interface )
• Web UI
• ACL ( access control )
• Data schema management and the integration with Google Cloud Storage.
Dremel• Analysis of crawled web documents
• Tracking install data for applications in the Android Market
• Crash reporting for Google products
• OCR results from Google Books
• Spam analysis
• Debugging of map tiles on Google Maps
• Tablet migrations in managed Bigtable instances
• Results of tests run on Google’s distributed build system
• Disk I/O statistics for hundreds of thousands of disks
• Resource monitoring for jobs run in Google’s data centers
• Symbols and dependencies in Google’s codebase
Dremel
• Columnar Storage
Dremel
• Tree architecture
https://cloud.google.com/files/BigQueryTechnicalWP.pdf
BigQuery vs MapReduce
Differences
• Dremel( BigQuery ) is designed as an interactive data analysis tool for large datasets ( not only programmer )
• MapReduce is designed as a programming framework to batch process large datasets ( only programmer )
DifferencesKey Differences BigQuery MapReduce
What is it? Query service for large datasetsProgramming model for processing large
datasets
Common use cases
Ad hoc and trial-and-error interactive query of large dataset for quick analysis and troubleshooting
Batch processing of large dataset for time-consuming data conversion or aggregation
Very fast response
Yes ( ~ 10 secs ) No ( takes minutes - days )
Easy to use Yes No ( requires Hive / Tenzing )
Programming complex data
processing logicNo Yes
Updating exsiting data
No Yes
BigQuery vs MapReduce
• BigQuery - 구조화된 데이터를 SQL을 사용해서 실시간으로 다루기 위해 디자인되었으며, CSV나 JSON을 통해 데이터를 import할 수 있으며, 등록된 데이터를 수정할 수 없다.
• MapReduce - 구조화되지 않은 데이터를 프로그램적으로 처리하는데 더 적합하며, 어떠한 데이터나 복잡한 로직도 적용 가능. 비실시간 데이터를 배치 작업을 통해서 결과를 얻어 오는데 적합하다.
BigQuery 용어
• Project - BigQuery 데이터의 컨테이너로 결제가 Project단위로 이루어짐. ACL 로 Project에서 제어합니다.
• Dataset - Dataset은 하나 이상의 Table 모음 ( like Database )
• Table - 일반적인 2차원 데이터 저장 묶음
• Job - Job은 데이터 쿼리, import, export, Table간 데이터 복사와 같은 장기 실행 Job을 관리하는데 사용
BigQuery 특징
• 오직 CR( Create and Read ) 만 가능 ( 데이터의 입력 및 읽기만 가능 )
• 삭제 단위는 최소 Table 단위
• 제한된 Join 지원
• 스키마
• Nested 테이블 구조 지원 ( Only JSON schema )
• No index
BigQuery 특징
• PaaS 의 장점을 그대로 계승
• 초기 투자 비용 없음
• 사용한 만큼 비용 지불
• 고급 시스템 운영 인력이 별도로 필요하지 않음
• 이만큼 더 빠르게 만들기 쉽지 않음 ( 몇십억 rows - 수초 이내 )
• 조단위의 레코드 지원 및 테라바이트 크기의 데이터 지원
• SQL 지원으로 편리하며 익숙함
Limitations
Limitation - Query
• 200GB의 동시 Query + 무제한 크기의 추가 Query 1개최대 20개의 동시 Query
• 일일 제한 : 20K Query
• 최대 쿼리 길이 : 10KB ( SQL )
• 최대 응답 크기 : 64MB
Limitation - Import
• 분당 2회
• 일일 1,000회 요청 ( 실패 포함 )
• 요청당 import 최대 파일 수 500개
• 파일당 최대 import 크기 4GB
• Job당 최대 import 크기 100GB
Limitation - Export
• 분당 2회
• 일일 50회
Price
가격정책
• 저장
• $0.12 ( GB / 월 )
• 최대 2TB
• 쿼리
• $0.035( 처리되는 GB당 ) - 최소 1MB
• 일일 20K 쿼리 ( QPD )
• 일일 20TB 데이터 처리
쿼리 비용 계산방법
• 샘플 Table - Wikipedia
• Table Size : 35.7GB
• Rows : 313,797,035
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 1 SELECT id FROM [publicdata:samples.wikipedia];
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 1 SELECT id FROM [publicdata:samples.wikipedia];
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 1 SELECT id FROM [publicdata:samples.wikipedia];
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 2 SELECT id FROM [publicdata:samples.wikipedia] LIMIT 100;
Query 3 SELECT id FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE ‘K%’ LIMIT 100;
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 2 SELECT id FROM [publicdata:samples.wikipedia] LIMIT 100;
Query 3 SELECT id FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE ‘K%’ LIMIT 100;
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 2 SELECT id FROM [publicdata:samples.wikipedia] LIMIT 100;
Query 3 SELECT id FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE ‘K%’ LIMIT 100;
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 2 SELECT id FROM [publicdata:samples.wikipedia] LIMIT 100;
Query 3 SELECT id FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE ‘K%’ LIMIT 100;
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 4 SELECT contributor_username, count(*) FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE 'K%' GROUP BY contributor_username;
쿼리 비용 계산방법
title id language revision_id contributor_username timstamp
Size (GB)
6.79 2.34 0.599 2.34 2.49 2.34
Type string integer string integer integer integer
Query 4 SELECT contributor_username, count(*) FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE 'K%' GROUP BY contributor_username;
쿼리 비용 계산방법Query 4 SELECT contributor_username, count(*) FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE 'K%' GROUP BY contributor_username;
쿼리 비용 계산방법Query 4 SELECT contributor_username, count(*) FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE 'K%' GROUP BY contributor_username;
쿼리 비용 계산방법Query 4 SELECT contributor_username, count(*) FROM [publicdata:samples.wikipedia] WHERE contributor_username LIKE 'K%' GROUP BY contributor_username;
위의 내용을 토대로 정리하면,
컬럼기반의 스토리지 특성상 컬럼의 사이즈를 기준으로 사용하는 컬럼의 용량만큼 과금된다.
( 다만, order by 시 사용되는 컬럼은 과금되지 않는 것으로 확인됩니다.
아마도 구조상 정렬없이 진행되는 건에 대한 데이터 일관성을 유지시켜줄 수 없는
구조상의 한계에 의한 것이 아닌가 조심스레 예상해봅니다. )
* 질의를 신경써서 구성해야 하며, 데이터 구성에 기존의 데이터에서 인덱스화 시켜야 하는 것들은 마찬가지로 데이터 용량을 최소하는 방향 ( 인덱스를 가볍게 만들 수 있는 )으로 설계
예상비용
* 가정 - 용량 변화 없음
* 비용 - 지금까지 질의한 4번의 쿼리 A. 저장비용 => 35.7GB * 0.12 = $4.284 ( 약 4,700원 )
B. 질의 비용 => 2.49 * 0.035 + 2.34 * 0.035 + 4.82 + 2.49 * 0.035 = $0.4249 ( 약 460원 )
비용합계( A + B ) => 4700 + 460 = 5,160원
Transaction DB 구축
목적 및 제약사항
• AppEngine의 로그를 조회하는 것이 한계가 있어 고객응대나 간헐적인 오류에 대한 패턴을 분석하기에는 부족 (This application stores up to 1000 GBytes of logs storage or 90 days of logs.)
• 계획되지 않은 통계 데이터 요청하는 경우가 발생
• 카운터 API를 생성하는 것과 같은 별도의 작업은 여러가지 정황상 불가능
• 서비스가 활성화됨에 따라 로그 로테이션 주기가 지속적으로 짧아짐
• 별도의 시스템을 운영하는 경우는 최소화 (AppEngine의 선택한 장점이 퇴색됨)
• 서비스에 영향 최소화
Main module
Plan
LogSystem
AppEngine
Compute Instance
BigQueryCloudStorageLogger Module
로그 정의
• 언제(A) 사용자(B)들이 무슨 플랫폼(C)을 사용하여 무슨 종류의 요청(D)을 하는지?
• 요청후 받아가는 결과(E)는 무엇이며, 내부 처리시간(F)을 얼마인가?
• A - date
• B - user_id, ip_address
• C - os, browser
• D - method, query, path
• E - response_code, response body
• F - duration
스키마 정의[{"name":"dt","type":"integer"},{"name":"cl","type":"RECORD","fields":[{"name":"uid","type":"STRING"},{"name":"ip","type":"STRING"},{"name":"os","type":"RECORD","fields":[{"name":"f","type":"STRING"},{"name":"v","type":"STRING"}]},{"name":"br","type":"RECORD","fields":[{"name":"f","type":"STRING"},{"name":"v","type":"STRING"}]}]},{"name":"rq","type":"RECORD","fields":[{"name":"m","type":"STRING"},{"name":"q","type":"STRING"},{"name":"p","type":"STRING"},{"name":"h","type":"RECORD","mode":"REPEATED","fields":[{"name":"k","type":"STRING"},{"name":"v","type":"STRING"}]}]},{"name":"rp","type":"RECORD","fields":[{"name":"c","type":"INTEGER"},{"name":"b","type":"STRING"},{"name":"d","type":"STRING"}]}]
스키마 정의[{"name":"dt","type":"integer"},{"name":"cl","type":"RECORD","fields":[{"name":"uid","type":"STRING"},{"name":"ip","type":"STRING"},{"name":"os","type":"RECORD","fields":[{"name":"f","type":"STRING"},{"name":"v","type":"STRING"}]},{"name":"br","type":"RECORD","fields":[{"name":"f","type":"STRING"},{"name":"v","type":"STRING"}]}]},{"name":"rq","type":"RECORD","fields":[{"name":"m","type":"STRING"},{"name":"q","type":"STRING"},{"name":"p","type":"STRING"},{"name":"h","type":"RECORD","mode":"REPEATED","fields":[{"name":"k","type":"STRING"},{"name":"v","type":"STRING"}]}]},{"name":"rp","type":"RECORD","fields":[{"name":"c","type":"INTEGER"},{"name":"b","type":"STRING"},{"name":"d","type":"STRING"}]}]
https://developers.google.com/bigquery/docs/developers_guide?hl=ko#tables
스키마 정의[{"name":"dt","type":"integer"},{"name":"cl","type":"RECORD","fields":[{"name":"uid","type":"STRING"},{"name":"ip","type":"STRING"},{"name":"os","type":"RECORD","fields":[{"name":"f","type":"STRING"},{"name":"v","type":"STRING"}]},{"name":"br","type":"RECORD","fields":[{"name":"f","type":"STRING"},{"name":"v","type":"STRING"}]}]},{"name":"rq","type":"RECORD","fields":[{"name":"m","type":"STRING"},{"name":"q","type":"STRING"},{"name":"p","type":"STRING"},{"name":"h","type":"RECORD","mode":"REPEATED","fields":[{"name":"k","type":"STRING"},{"name":"v","type":"STRING"}]}]},{"name":"rp","type":"RECORD","fields":[{"name":"c","type":"INTEGER"},{"name":"b","type":"STRING"},{"name":"d","type":"STRING"}]}]
https://developers.google.com/bigquery/docs/developers_guide?hl=ko#tables
https://cloud.google.com/bigquery/docs/data#nested
BigQuery CloudStorage 신청
• 기본적으로 Google Cloud Storage 는 신청되어 있음
• BigQuery API를 활성화 하면 바로 사용 가능
CloudStorage Bucket 생성• bucket ( 일종의 folder 개념 ) 을 생성
• 구성상 다른 AppEngine 모듈 및 ComputeEngine에서 접근할 수 있도록 권한 수정
• [project-id]@appspot.gserviceaccount.com
CloudStorage Bucket 생성• bucket ( 일종의 folder 개념 ) 을 생성
• 구성상 다른 AppEngine 모듈 및 ComputeEngine에서 접근할 수 있도록 권한 수정
• [project-id]@appspot.gserviceaccount.com
CloudStorage Bucket 생성• bucket ( 일종의 folder 개념 ) 을 생성
• 구성상 다른 AppEngine 모듈 및 ComputeEngine에서 접근할 수 있도록 권한 수정
• [project-id]@appspot.gserviceaccount.com
BigQuery Dataset 생성
• dataset ( RDBMS의 Database ) 를 생성
• 권한은 BigQuery를 접근하는 google compute engine이 동일한 project 이어서 별다른 설정이 필요하지 않음
BigQuery Dataset 생성
• dataset ( RDBMS의 Database ) 를 생성
• 권한은 BigQuery를 접근하는 google compute engine이 동일한 project 이어서 별다른 설정이 필요하지 않음
로그 입력 테스트
• Google Cloud SDK를 설치 및 project 설정 진행https://cloud.google.com/sdk/
• import 시에는 반드시 gz 압축은 필수, —nosync 옵션도 필수
# bq 명령어 : https://developers.google.com/bigquery/docs/cli_tool?hl=ko
Log 데이터 생성 script• https://gist.github.com/judeKim/2abc98d05ecc5c2a9d17
PHP
BigQuery에 질의하기• BigQuery 콘솔에 접속
( https://bigquery.cloud.google.com/queries/[project_id] )
BigQuery에 질의하기• BigQuery 콘솔에 접속
( https://bigquery.cloud.google.com/queries/[project_id] )
BigQuery에 질의하기• BigQuery 콘솔에 접속
( https://bigquery.cloud.google.com/queries/[project_id] )
BigQuery에 질의하기• BigQuery 콘솔에 질의하기
BigQuery에 질의하기• BigQuery 콘솔에 질의하기
BigQuery에 질의하기• BigQuery 콘솔에 질의하기
BigQuery에 질의하기• BigQuery 콘솔에 질의하기
BigQuery에 질의하기• BigQuery 콘솔에 질의하기
BigQuery에 질의하기• BigQuery 콘솔에 질의하기
BigQuery에 질의하기 - Join• 소규모 조인을 지원 - 테이블이 압축했을때 8MB이하일때 가능
( 8MB 제한은 향후 개선될 수 있음 )
• INNER 및 LEFT OUTER JOIN 을 지원
BigQuery에 질의하기• SELECT
• FROM
• JOIN
• WHERE
• HAVING
• GROUP BY
• ORDER BY
• LIMIT
• 집계 함수
• 산술 및 수학 함수
• 비트함수
• 캐스팅 함수
• 비교 함수
• IP 함수
• 논리 연산자 함수
• 정규 표현식 함수
• 문자열 함수
• 타임스탬프 함수
• 기타 함수
Data 내보내기
A. 질의한 결과의 행이 16,000개 이하일 경우 CSV로 저장
B. 결과를 또 하나의 BigQuery 테이블로 저장
C. Google Cloud Storage로 분할 파일 저장
https://cloud.google.com/bigquery/exporting-data-from-bigquery?hl=ko
Conclusion
BigQuery는?
• 저장 인프라의 제약 사항에 대해서 신경쓰지 않고 마구 집어 넣어놓고 질의해보기는 괜찮다.
• 비용을 생각한다면 몇가지 최적화 및 코드화 처리는 필수적이다.
• 구글 클라우드 플랫폼을 사용하고 있지 않다면, 다소 불편할 수 있다.
• 통계화 진행하기 위한 중간 데이터 저장소로 사용하는 것도 나쁘지 않다.
• 하둡 운영할 자신이 없다면 BigQuery를 선택해보는 것도 좋다.
BigQuery는?
• 저장 인프라의 제약 사항에 대해서 신경쓰지 않고 마구 집어 넣어놓고 질의해보기는 괜찮다.
• 비용을 생각한다면 몇가지 최적화 및 코드화 처리는 필수적이다.
• 구글 클라우드 플랫폼을 사용하고 있지 않다면, 다소 불편할 수 있다.
• 통계화 진행하기 위한 중간 데이터 저장소로 사용하는 것도 나쁘지 않다.
• 하둡 운영할 자신이 없다면 BigQuery를 선택해보는 것도 좋다.
감사합니다.
References
• https://developers.google.com/bigquery/?hl=ko
• https://cloud.google.com/files/BigQueryTechnicalWP.pdf
• https://cloud.google.com/bigquery/what-is-bigquery?hl=ko
• https://docs.google.com/presentation/d/1sqOY7D8k4qzPaAy4X70rY3F6zUx8bEA4euTjJ0MlUeY/view?pli=1#slide=id.p18