본문 바로가기

data engineering/hadoop

Apache Hive -1 (핵심 구성 요소와 개념)

https://nani-log.tistory.com/160

 

Hadoop Ecosystem 쓱 보기 -3 (Hive)

https://nani-log.tistory.com/159?category=720053 Hadoop Ecosystem -2 (Mapreduce2, YARN)https://nani-log.tistory.com/158 Hadoop Ecosystem -1 (HDFS, MapReduce1)데이터 웨어하우스를 공부하다보니, 분산시스템의 근간인 하둡 에코시

nani-log.tistory.com

 

Hadoop Ecosystem 쓱 보기를 통해 Hive의 대략적인 구성요소를 살펴봤다. 이번 포스트에선 조금 더 깊이 Hive에 대해 알아보자

 

1. 설계

실행 엔진

Hive의 기본 실행 엔진은 Mapreduce다. 실행 엔진은 말 그대로 사용자가 HiveQL로 쿼리를 실행하려고 할때 실질적으로 그 쿼리에 대한 결과를 제공하기 위해 실행하는 소프트웨어를 말한다

 

하지만 앞서 말했듯 Mapreduce는 중간 결과가 디스크에 저장되고 배치 처리를 위해 설계되어 있어 성능면에서 실시간 분석 쿼리를 실행하기엔 적절하지 않았다. 그래서 사람들은 Tez 혹은 Spark를 실행 엔진으로 설치해 사용하는 것이 더 일반적이게 됐다

 

실행 엔진은 쿼리 단위로 쉽게 전환해 사용할 수도 있다. 예를 들어, 하둡 클러스터에 Tez가 설치되어 있다면, 쿼리 실행시 엔진을 Tez로 설정하고 실행해볼 수 있다. 이로 인해 다양한 엔진의 성능을 확인할 수 있다는 장점이 있다

 

 

Hive 메타스토어

메타스토어는 하이브 메타데이터의 핵심 저장소로, Hive 테이블, 스키마, 파티션 정보 등을 저장하고 관리한다. 크게 서비스와 데이터 보관 저장소로 구성되는데 저장소는 보통 MySQL, PostgreSQL, Oracle과 같은 RDBMS을 사용한다

 

Hive는 이 메타데이터를 기반으로 HDFS와 같은 분산 스토리지에 저장된 데이터를 읽고, 쓰고, 질의하는 것이다

[출처] 하둡 완벽 가이드

 

 

 

HiveQL

Hive의 SQL 언어로 SQL-92, MySQL, Oracle SQL을 혼합한 형태다. 특히 Mapreduce에서 영감을 얻은 TRANSFORM, MAP, REDUCE 절이 있다는게 특징이다

 

기본, 복합 자료형을 모두 지원하며 연산자는 MySQL의 연산자와 거의 일치한다. 원하는 기능을 지원하는 내장 함수가 없을땐 직접 작성할 수도 있다

 

 

2.  데이터 저장

Hive 테이블

Hive 테이블은 '저장된 데이터'와 '테이블에서 데이터의 배치를 기술하는 관련 메타데이터'로 구성된다. 데이터는 로컬 파일시스템이나 S3를 포함해 어떤 하둡 파일시스템에도 둘 수 있지만 기본적으론 HDFS에 둔다. 메타데이터는 HDFS가 아닌 관계형 데이터베이스에 저장한다

 

테이블 생성시 기본적으론 데이터를 자신이 관리하는 웨어하우스 디렉터리로 이동시키는데, 이는 데이터를 직접 관리한다는 차원에서 관리 테이블이라 부르며 반대로 웨어하우스 디렉터리 외부의 데이터를 참조해 외부 테이블을 생성할 수도 있다

 

이 두 테이블의 차이는 DROP 명령어를 사용시 두드러지는데, 관리 테이블을 DROP하면 메타데이터와 디렉터리 내 데이터를 삭제하지만 외부 테이블을 DROP하면 메타데이터만을 삭제한다

 

Hive 내에서만 데이터를 처리한다면 관리 테이블을, 동일한 데이터셋을 하이브를 비롯해 다른 도구와 함께 사용한다면 외부 테이블을 주로 선택한다

 

 

파티션과 버킷

Hive는 테이블을 파티션으로 구조화할 수 있는데, 파티션 컬럼 값을 기반으로 큰 단위로 분할하는 방식이다. 파티션 사용시 특정 컬럼을 기반으로 해당하는 파티션만 검색할 수 있어 빠르게 쿼리를 처리할 수 있다. 이를 입력 가지치기(input pruning)라고도 한다

 

이에 더해 파티션 내 데이터를 파일 수준에서 더 세분화해 버킷으로 저장할 수 있다. 동일한 컬럼(조인할 컬럼)을 가진 두 테이블에 대해 버켓팅을 실행하면 두 테이블을 조인할 때 성능이 향상되며, 매우 큰 데이터셋을 버킷으로 나누면 데이터를 필요한 일부만 검색할 수 있어 효율적이다. 일종의 클러스터링이라고 보면 될 것 같다

 

 

3. 데이터 쿼리

조인

Mapreduce로 조인을 구현하려면 매우 복잡하다. Hive는 이 어려움을 해결하기 위해 만들어졌기에 Hive를 통해 조인을 수행하는 것은 아주 큰 장점이다

 

조인에 여러 종류가 있는데, 내부 조인, 외부 조인, 세미 조인, 맵 조인이 있다

  1. 내부 조인
    • 가장 단순한 종류의 조인으로 두 개의 입력 테이블에서 일치한 행을 하나의 행으로 출력하는 내부 조인이다
  2. 외부 조인
    • 조인할 상대 테이블에 일치하지 않는 데이터도 출력되는 조인이다
  3. 세미 조인
    • 두 테이블을 조인할 때, 하나의 테이블에서 조인 조건을 만족하는 행만 반환한다
    • 서브쿼리에 해당하는 부분을 세미 조인으로 구현할 수 있다
  4. 맵 조인
    • 특정 테이블의 내용이 메모리에 모두 들어갈 수 있을 정도로 작을때, 각 매퍼에서 조인을 수행할 수 있도록 모든 데이터를 메모리에 로드할 수 있다. 맵 단계에서 수행되는 조인으로 맵 조인이라고 한다
    • 성능 최적화를 위해 사용된다

 

 

서브 쿼리

SELECT 구문의 FROM절과 WHERE 절에서만 서브쿼리를 사용할 수 있다

 

 

뷰는 다른 데이터베이스에서와 마찬가지로 가상 테이블이다. 뷰를 생성하면 디스크에 실제 저장되진 않고 메타스토어에만 저장되며 테이블의 특정 부분에만 접근할 수 있도록 제한하는데 사용될 수도 있다

 

 

사용자 정의 함수(UDF)

Hive가 제공하는 내장 함수로 원하는 쿼리를 작성할 수 없거나 쉽지 않을때 사용자 정의 함수를 작성할 수 있다. 사용자 정의 함수는 자바로 작성해야 한다

 

 

4. 전통적인 데이터베이스와의 차이

MySQL, PostgreSQL과 같은 전통적인 데이터베이스와 여러 면에서 비슷하다. 하지만 Hive는 HDFS와 Mapreduce를 기반으로 개발되어 몇가지 차이점을 보인다

 

  1. 읽기 스키마(Schema on Read)
    • 전통적인 데이터베이스에서는 테이블의 스키마가 데이터를 로드하는 시점에 검증된다. 예를 들어, 데이터를 테이블에 쓰려고 할 때, 스키마에 부합되지 않으면 해당 데이터를 거부한다. 이를 쓰기 스키마라고 한다
    • 하지만 Hive는 쿼리를 실행할 때 스키마를 기반으로 데이터를 해석한다. 이를 읽기 스키마라고 하는데, 데이터를 단순히 복사하거나 이동해두고 쿼리 실행시 쿼리의 목적에 맞게 변환하고 분석할 수 있다
  2. 갱신, 트랜잭션, 인덱싱
    • 전통적인 데이터베이스에선 핵심적인 기능이지만 최근까지 Hive는 이런 특성을 고려하지 않았다. HDFS와 Mapreduce가 기반이었기 때문에 전체 테이블을 스캔하는 방식만 제공했지만, 최신 버전에서는 INSERT, UPDATE, DELETE가 가능하게 됐다
    • 테이블과 파티션 수준의 잠금을 지원한다. 마치 thread-safe하게 잠금을 지원하는 것처럼 특정 프로세스가 테이블을 읽는 도중에 다른 프로세스가 테이블을 삭제하는 것을 방지한다
    • Hive는 쿼리의 속도를 높일 수 있는 인덱싱을 지원한다. 콤팩트 인덱싱과 비트맵 인덱싱이 있고 인덱싱을 통해 필요한 블록만 읽을 수 있어 효율이 높아진다

 

 

정리

현대 데이터 웨어하우스로 많이 선택되는 Bigquery, Redshift 등이 Hive와 많이 닮아있다는걸 느낄 수 있었다. 데이터를 저장할 때부터 파티션과 버킷을 이용해 쿼리 성능을 높이려는 노력이 특히 눈에 띄었다

 

비록 성능상의 이유로 실행 엔진을 교체하고 Hive를 대체하려는 도구들이 개발되었지만, 빅데이터 환경에서 최초로 SQL 기반 인터페이스를 제공한 시스템이라는 점에서 여전히 중요한 의미를 가지는 것 같다

 

 

 

 

[참고] 하둡 완벽 가이드