빅쿼리 #2-아키텍쳐
조대협 (http://bcho.tistory.com)
이번글에서는 앞에서 소개한 구글의 대용량 데이타 저장/분석 시스템인 빅쿼리의 내부 아키텍쳐에 대해서 알아보도록 한다.
컬럼 기반 저장소
다음과 같은 테이블이 있다고 하자
전통적인 데이타 베이스는 파일에 물리적으로 데이타를 저장할때 개념 적으로 다음과 같은 방식으로 저장한다.
FILE 1 : “001;Cho;Terry;Seoul;30,002;Lee;Simon;Suwon;40,003;Kim;Carl;Busan;22”
그래서 하나의 레코드를 가지고 오면 그 레코드에 해당하는 모든 값을 가지고 올 수 있다.
반면 컬럼 기반 저장소의 경우에는 각 컬럼을 다음과 같이 다른 파일에 나눠서 저장한다.
FILE 1: 001:Cho,002:Lee,003:Kim
FILE 2: 001:Terry,002:Simon,003:Carl
FILE 3: 001:Seoul;002:Suwon:003:Busan
:
이렇게 컬럼 단위로 저장을 하게 되면 장점은 Last Name 컬럼의 내용만 읽고 싶을때 로우 단위로 저장한 시스템의 경우, 모든 데이타를 다 스캔해야 하는데, 컬럼 단위로 저장한 시스템은 Last Name을 저장한 파일 하나만 스캔하면 되고, Last Name 이외의 다른 컬럼의 데이타는 읽어드리지 않아도 되기 때문에 데이타 효율성이 높다.
그래서 특정 컬럼만 읽어서 개수를 세거나 통계를 내는 분석용 데이타 베이스(OLAP) 작업등에 유리하다.
“Columnar databases boost performance by reducing the amount of data that needs to be read from disk, both by efficiently compressing the similar columnar data and by reading only the data necessary to answer the query.
In practice, columnar databases are well-suited for OLAP-like workloads (e.g., data warehouses) which typically involve highly complex queries over all data (possibly petabytes). However, some work must be done to write data into a columnar database. Transactions (INSERTs) must be separated into columns and compressed as they are stored, making it less suited for OLTP workloads. Row-oriented databases are well-suited for OLTP-like workloads which are more heavily loaded with interactive transactions.”
출처 : https://en.wikipedia.org/wiki/Column-oriented_DBMS
실제로 빅쿼리도 하나의 파일에 하나의 컬럼 데이타만 저장하도록 되어 있다.
빅쿼리는 앞의 글에서도 설명하였듯이 데이타의 안정성을 위해서 3개의 데이타 센터에 나눠서 데이타를 저장하는데, 각 컬럼을 저장하는 파일이 총 3개의 복제본으로 그림과 같이 각각 다른 데이타 센터에 나줘서 저장이 된다.
트리 구조의 데이타 처리 구조
실제로 빅쿼리의 시스템 구조는 다음과 같이 되어있다.
출처 https://codelabs.developers.google.com/codelabs/cp100-big-query/#3
GFS (Google File System)의 후속 파일 시스템인 분산 스토리지 Colossus가 맨 아래에서 저장소를 제공하고, Jupiter 라는 TB 급의 네트워크 망을 통해서, 컴퓨팅 노드와 통신을 한다.
그리고 연산을 담당하는 컴퓨팅 계층은 Leaf , Mixer 1, Mixer 0 계층으로 되어 있다.
이 컴퓨팅 계층은 디스크 없이 Colossus에서 읽은 데이타를 처리해서 각각 위의 계층으로 올리는 역할을한다.
다음 SQL이 어떻게 연산이 수행되는지를 살펴보면 아키텍쳐를 이해할 수 있다.
natality라는 테이블에서 1980~1990년대에 태어난 아이들의 수를 주(state)별로 그룹핑해서 내림차순으로 정렬한 후 상위 10개의 데이타만 출력해주는 쿼리이다.
이 쿼리를 수행하면 빅쿼리는 내부적으로 다음과 같은 연산을 수행한다.
STORAGE : 디스크에서 STATE,YEAR 컬럼만을 읽어드린다.
LEAF : 다음 각각의 LEAF 노드에서, 읽어드린 데이타를 가지고 1980~1990년대 데이타를 주 단위로 태어난 아이들의 수를 카운팅 한다.
MIXER 1:에서 LEAF에서 계산해온 주(STATE) 별 아이들의 수를 합친다.
MIXER 0:에서는 MIXER 1에서 올라온 모든 값을 합치면서 소팅을 한다. (머지 소트를 생각하면 된다.). 소팅이 끝난 후에, 맨 위의 10개의 레코드만을 리턴한다.
조인이나 그룹핑의 경우 조금 더 복잡한 연산이 실행되기는 하지만 큰 흐름은 유사하다.
다른 구조적인 특징
빅쿼리가 대용량과 성능을 지원하기는 하지만 일반적인 데이타 베이스와 다소 다른 특성을 가지고 있다.
NO-KEY,NO-INDEX (FULL SCAN ONLY)
빅쿼리에는 키나 인덱스의 개념이 없다. 무조건 풀스캔이다. (스캔의 범위를 조정할 수 있는 기법이 있는데 이는 나중에 설명하도록 한다.)
NO UPDATE,DELETE ROW
빅쿼리는 성능을 위해서 테이블에 데이타를 추가 (APPEND)하는 것만을 지원한다. 한번 입력된 데이타는 변경되거나 삭제될 수 없으며, 데이타가 잘못 입력되었을 경우에는 테이블을 지우고 다시 생성해야 한다. (이 문제를 해결하는 디자인 패턴에 대해서는 나중에 설명한다.)
EVENTUAL CONSISTENCY
데이타를 3개의 데이타 센터에 걸쳐서 복제하기 때문에, 데이타를 입력한 후 바로 조회하면 데이타가 조회가 되지 않을 수 있다. 이는 데이타를 복제하는데 소요되기 때문인데, 보통 바로 반영되거나 상황에 따라서 최대 수분이 걸릴 수 있다.
다음 글에서는 빅쿼리의 데이타 모델과 인터페이스에 대해서 알아보도록 한다.
참고 자료
- https://cloud.google.com/files/BigQueryTechnicalWP.pdf
- http://www.slideshare.net/sawjd/an-indepth-look-at-google-bigquery-architecture-by-felipe-hoffa-of-google
- https://www-conf.slac.stanford.edu/xldb2012/talks/xldb2012_tue_1415_RyanBoyd.pdf
'빅데이타 & 머신러닝 > Google BigQuery' 카테고리의 다른 글
빅쿼리 대쉬 보드를 위한 오픈소스 메타 베이스 (3) | 2018.01.31 |
---|---|
빅쿼리를 이용하여 두시간만에 트위터 실시간 데이타를 분석하는 대쉬보드 만들기 (3) | 2016.08.01 |
빅데이타 수집을 위한 데이타 수집 솔루션 Embulk 소개 (1) | 2016.07.31 |
빅쿼리-#3 데이타 구조와 접근(공유) (3) | 2016.06.18 |
구글 빅데이타 플랫폼 빅쿼리(BIGQUERY)에 소개 (0) | 2016.06.15 |