전통적인 데이터베이스와의 비교


하이브는 전통적인 데이터베이스와 여러 면에서(SQL 인터페이스 지원 등) 비슷하다. 하지만 하이브는 HDFS와 맵리듀스를 기반으로 개발되었고, 이는 하이브가 제공하는 기능에 직접적으로 영향을 주기 때문에 아키텍처 측면에 일부 차이가 있을 수 밖에 없다. 하지만 시간이 흘러 이러한 제약은 점차 사라지고 있으며, 그 결과 하이브는 해가 지날수록 전통적인 데이터베이스와 점차 비슷해지고 있다.



읽기 스키마와 쓰기 스키마 비교

전통적인 데이터베이스에서 테이블의 스키마는 데이터를 로드하는 시점에 검증된다. 만일 로드중인 데이터가 스키마에 부합되지 않으면 해당 데이터를 거부한다. 이러한 설계 방식을 쓰기 스키마라고 부르는데, 데이터베이스에 쓰는 시점에 데이터의 스키마를 검증하기 때문이다.

한편 하이브는 로드 시점이 아니라 쿼리를 실행할 때 그 데이터를 검증한다. 이를 읽기 스키마라고 한다.

두 방식은 서로 상충 관계가 있다. 읽기 스키마는 데이터베이스 내부 형식으로 데이터를 읽거나 파싱하거나 디스크에 직렬화할 필요가 없기 때문에 초기에 매우 빠른 속도로 데이터를 로드할 수 있다. 따라서 로드 조작을 위해서는 단순히 파일을 복사하거나 이동하기만 하면 된다. 데이터 분석의 목적에 따라 동일한 데이터를 두 스키마로 다룰 때를 생각해보면 읽기 스키마는 매우 유연하다. 또한 하이브는 외부 테이블도 사용할 수 있다.

쓰기 스키마는 데이터베이스가 컬럼 단위의 데이터 색인과 압축을 제공하기 때문에 더 빠르게 쿼리를 수행할 수 있다. 하지만 상대적으로 데이터베이스에 데이터를 로드하는 시간은 더 오래 걸린다. 더욱이 쿼리가 정해지지 않아서 로드 시점에 스키마를 지정할 수 없고 색인도 적용할 수 없는 경우도 빈번하다.



갱신, 트랜잭션, 색인

갱신, 트랜잭션, 색인은 전통적인 데이터베이스의 핵심 기능이다. 그럼에도 최근까지 하이브는 이러한 특성을 고려하지 않았다. 그 ㄷ이유는 하이브가 맵리듀스를 사용하는 HDFS에 저장된 데이터를 다루기 대문이다. 이러한 환경에서 하이브의 기본 기능은 전체 테이블을 스캔하는 방식으로만 구현되어 있다. 실제 테이블의 갱신은 아예 새로운 테이블을 만들어 데이터를 변환하는 방식으로 구현된다. 이것은 대량의 데이터셋을 대상으로 실행되는 데이터웨어하우징 어플리케이션에서 잘 작동하는 방식이다.

최근까지 하이브에서 기존 테이블에 새로운 열을 추가하는 기능은 INSERT INTO를 이요하여 테이블에 새로운 데이터 파일을 추가하는 방식만 가능했다. 하지만 0.14.0 버전 부터는 INSERT INTO TABLE ... VALUES 를 이용하여 SQL로 계산된 작은 값의 집합을 추가하는 것도 지원하기 시작했다. 게다가 테이블의 행에 대해 UPDATE 및 DELETE 조작도 가능하다.

HDFS는 기존 파일의 갱신을 지원하지 않기 떄문에 삽입, 변경, 삭제로 인한 갱신 내역을 별도의 작은 델타 파일에 저장된다. 델타 파일은 메타스토어에서 백그라운드로 실행되는 맵리듀스잡에 의해 기존 테이블과 주기적으로 병합된다. 이 기능은 하이브 0.13.0에서 처음 도입된 트랜잭션 콘텍스트에서만 작동하고, 트랜잭션이 활성화된 테이블에만 적용된다. 테이블을 읽는 쿼리는 일관된 테이블 스냅샷을 보장받는다.

하이브는 추가로 테이블과 파티션 수준의 잠금을 지원한다. 예를 들어 잠금은 특정 프로세스가 테이블을 읽는 도중에 다른 프로세스가 테이블을 삭제하는 것을 방지할 수 있다. 잠금은 주키퍼에 의해 투명하게 관리되므로 사용자가 직접 주키퍼를 조작하여 잠금을 적용하거나 해제할 수는 없다. 하지만 SHOW LOCKS 구문을 통해 잠금의 적용 여부에 대한 정보는 얻을 수 있다. 잠금 기능은 기본적으로 활성화되어 있지 않다.

하이브는 특정한 경우에 쿼리의 속도를 높일 수 있는 색인을 지원한다. 예를 들어 SELECT * FROM T WHERE X = A 와 같은 쿼리는 X 컬럼에 대한 색인을 이용할 수 있기 때문에 해당 테이블 파일의 일부만 읽어 들인다. 현재 콤팩트 색인과 비트맥 색인을 지원한다. 색인은 플러그인 방식으로 구현되었기 때문에 다른 방식의 색인도 추가할 수 있다.

콤팩트 색인은 각 값을 파일 오프셋이 아닌 HDFS 블록 넘버로 저장한다. 따라서 디스크 공간을 많이 차지하지 않으면서도 인접한 행 사이에 분포된 특정 컬럼에 대한 값을 색인하는 데 매우 효율적이다. 비트맵 색인은 특정 값이 출현하는 행을 효율적으로 저장하기 위해 압축된 비트셋을 사용한다. 일반적으로 이 방식은 성별이나 국가처럼 값의 종류가 적은 컬럼에 적합하다.



SQL-on-Hadoop 대안


  • 임팔라 : 최초의 엔진 중 하나로 맵리듀스 기반으로 실행되는 하이브에 비해 성능이 한 단계 향상. 임팔라는 클러스터의 각 데이터노드에서 실행되는 전용 데몬을 사용한다. 클라이언트가 임팔라 데몬이 실행되는 임의의 노드에 접속하여 특정 쿼리를 실행하면 그 노드는 해당 쿼리를 총괄하는 코디네이터 노드의 역할을 맡게 된다. 코디네이터는 클러스터에 있는 다른 여러 개의 임팔라 데몬으로 작업을 보내고 각 데몬의 수행 결과를 해당 쿼리의 최종 결과 집합으로 결합한다. 임팔라는 하이브의 메타스토어를 이용하고 하이브 포맷과 대부분의 HiveQL 구문을 지원한다. 따라서 실질적으로 두 시스템이 통합되어 있다고 볼 수 있고, 동일한 클러스터에서 하이브와 임팔라를 둘 다 실행할 수 있다.

  • 테즈 : 임팔라 등장 후 호튼웍스에서 새로운 실행 엔진인 테즈(Tez)를 통해 하이브의 성능을 향상시키는 스팅거(Stinger) 이니셔티브를 시작. 성능 개선을 위해 벡터 쿼리 엔진을 추가

  • 프레스토 : 임팔라와 비슷한 아키텍처를 가지고 있다.

  • Spark SQL : 스파크를 기반 엔진으로 이용하고 스파크 내장 SQL 쿼리를 허용한다.