“카카오의 오픈소스를 소개합니다” 네번째는 terence.yoo와 동료들이 개발한 HBase Tools입니다.

[HBase Tools]는 카카오에서 대규모 HBase 클러스터를 운영하면서 만들어진 도구들을 하나로 묶은 것입니다.​

HBase 주요 버전별 빌드를 제공하고 있어서 가져도 쓰기도 좋지만, HBase의 부실한 도구들 때문에 고생하셨던 분들에겐 나만의 HBase 도구를 만드는 좋은 시작점이 될 것입니다.

1. hbase-tools 소개

툴을 사용하면 HBase 운영 작업의 효율성이 좋아집니다. 카카오에서 사용하는 대표적인 툴 세 가지는 HBase Shell, HBase Web UI, Cloudera Manager Express Edition(이하 CM)입니다. 이 툴들은 매우 우수하지만, 꼭 필요한 기본적인 기능들만 제공합니다. 그래서 그런 기본적인 기능들을 코딩을 통해 이리저리 조합해서 사용해야 하는 경우가 많습니다. 심지어 어떤 기능들은 유료 버전에서만 사용가능 한 것들도 있습니다. 이런 부족한 부분을 채우기 위해서 툴을 하나, 둘 만들었습니다. 툴들이 여럿 쌓이다 보니 관리가 불편하게 되었고, 관리를 편하게 하기 위해서 하나로 모은 것이 hbase-tools입니다.

hbase-tools는 세 가지 모듈로 이루어져 있고, 각 모듈 별 주요 기능은 다음과 같습니다.

  • hbase-table-stat Module
  • Table Metrics Monitoring
  • hbase-manager Module
  • Region Assignment Management
  • Advanced Split
  • Advanced Merge
  • Advanced Major Compaction
  • hbase-snapshot Module
  • Table Snapshot Management

지금부터 위에 나열한 순서대로 각 모듈 별 기능들에 대해서 설명하겠습니다.

참고: 이 글은 툴의 기능에 대해서 개념적인 소개에 대해서만 다루고 있습니다. 모듈의 구조와 툴의 구체적인 사용방법은 Introduction And Use Cases 문서를 참고하세요.

2. hbase-table-stat

HBase 클러스터의 상태는 메트릭을 통해서 확인이 가능합니다. 메트릭을 조회할 수 있는 방법은 두 가지가 있습니다. 첫번째가 HBase Web UI를 이용하는 것이고, 두번째가 CM을 이용하는 것입니다. HBase Web UI에서는 리전서버(region server) 중심의 메트릭을 텍스트 포맷으로 조회할 수 있습니다. CM에서는 CM 차트라는 기능으로 메트릭을 그래프 형태로 조회할 수 있습니다. CM 차트는 리전서버 레벨뿐만 아니라 테이블 레벨의 메트릭을 그래프로 조회할 수도 있습니다.

성능 모니터링을 할 때는 작업 단위가 테이블일 경우가 많기 때문에 테이블 중심으로 메트릭을 조회해야 하는 경우가 많습니다. 하지만 위에서 언급한 툴들은 메트릭을 테이블 중심으로 조회하고자 할 때 어려움이 있습니다. 첫째로 테이블 중심의 메트릭을 조회하는 기능이 아예 없거나 있더라도 빈약합니다. HBase Web UI에는 테이블 별로 메트릭을 집계 하는 기능이 없고, CM에서는 테이블 별로 집계는 가능하나 여러 테이블의 여러 메트릭을 한 눈에 확인하기가 불편합니다. 둘째로 메트릭의 변화량을 민첩하게 보여주지 못합니다. HBase Web UI는 변화량을 보여주는 기능이 아예 없고, CM은 갱신 주기가 길어서 세밀한 변화를 빠르게 모니터링 하기에는 부족합니다.

hbase-table-stat

이러한 부족함을 해결하기 위해서 dstat, vmstat, iostat 류의 커맨드라인 툴들과 비슷한 hbase-table-stat을 만들었습니다. hbase-table-stat은 커맨드라인에서 작동하며 10초(기본값, 변경 가능) 간격으로 여러 개의 메트릭을 조회해서 보여 줍니다. 이때 모든 메트릭들은 테이블 중심으로 집계됩니다. 또한 매트릭의 절대값 뿐만 아니라, 변화량 까지 한 번에 보여주어서 한 눈에 여러 정보를 확인 할 수 있습니다. 그리고 각 메트릭 별로 소트도 가능합니다. 웹서버 기능을 내장하고 있어서 커맨드라인에서 보이는 내용 그대로를 웹브라우저를 통해서 다른 사용자들에게 공유할 수도 있습니다.

3. hbase-manager

리전서버에 분산된 HBase의 테이블

HBase에서 데이터는 테이블(table)에 저장되고, 각 테이블은 리전(region)이라는 단위로 나뉘어져서 리전서버에서 서비스 됩니다. 그래서 HBase 운영 과정에서는 테이블과 리전을 잘 다루는 기술이 중요합니다. 테이블이나 리전 관리는 보통 쉘(HBase shell)에서 하게 되는데, 쉘에서는 split, merge, major compact, balance, move 등의 기본적인 기능들만 제공하고 있습니다. 복잡한 작업을 할 때는 이런 기본 기능들을 조합해서 사용해야 합니다.

그래서 자주 하는 작업들에 대해서는 미리 효율적이면서 잘 테스트 된 툴을 만들어 두고, 그 툴을 이용하면 실수 없이 빠르게 작업을 진행할 수가 있습니다. 그렇게 해서 만들어진 것이 hbase-manager입니다. 현재 hbase-manager에서 제공하는 기능은 리전 배치 관리, 스플릿, 머지, 메이저 컴팩션 크게 네 가지 입니다.

3.1 Region Assignment Management

3.1.1 리전서버 재시작

하드웨어 점검이나 HBase 설정 변경 등의 이유로 리전서버를 재시작 해야 하는 경우가 있습니다. 이런 경우 hbase-manager를 이용하면 서비스에 미치는 영향을 최소화 하면서 재시작을 할 수 있습니다. 리전서버 재시작 과정은 아래와 같습니다.

  1. Automatic Load Balancer를 끕니다.
  2. 재시작 하려고 하는 리전서버에서 서비스 중인 모든 리전을 다른 리전서버들로 골고루 흩어서 옮겨 줍니다.
  3. 리전서버를 셧다운 하고, 점검이나 설정 변경을 진행합니다. 이때 Data Node, Task Tracker 등도 필요하면 셧다운 합니다.
  4. 작업이 완료되면 리전서버를 다시 올리고, 리전서버에서 이전에 서비스하던 리전들을 다시 옮겨 옵니다. 이렇게 하면 데이터 로컬리티(data locality) 저하를 최소화 할 수 있습니다.
  5. Automatic Load Balancer를 켭니다.

이런 과정을 전체 RS에 적용하면 클러스터를 롤링리스타트(rolling restart) 할 수 있습니다. CM Express Edition에서는 롤링리스타트 기능을 제공하고 있지 않기 때문에, 카카오에서는 자체적으로 hbase-manager의 기능을 사용해서 롤링리스타트 툴을 만들어서 사용하고 있습니다.

3.1.2 밸런싱

간혹 리전이 리전서버에 골고루 분포되지 않았거나, 어떤 테이블의 리전이 일부 리전서버에 몰려 있어서 클러스터가 비효율적으로 운영될 때가 있습니다. 이런 경우에는 운영자가 수동으로 밸런싱을 해야 합니다. HBase Shell에서 move 커맨드를 이용해서 특정 리전을 특정 리전서버로 옮겨주면 리전 불균형 문제를 해소할 수 있습니다. 하지만 옮겨야 할 리전이 많을 경우에는 이런 방법은 매우 비효율적입니다. 이런 경우에 hbase-manager를 이용하면 간단하고도 빠르게 밸런싱 작업을 할 수 있습니다.

hbase-manager는 테이블 단위로 룰을 적용해서 밸런싱을 합니다. 사용할 수 있는 룰은 Round-robin, Random, Stochastic 세가지 입니다.

  • Round-robin: 테이블의 모든 리전을 순서대로 모든 리전서버를 돌아가며 하나씩 할당하는 과정을 반복합니다. 리전과 리전서버 목록이 바뀌지 않는다면 여러 번 실행하더라도 동일한 밸런싱 결과를 얻을 수 있습니다.
  • Random: 내부적으로 Round-robin과 거의 비슷한 방식으로 작동하지만 리전이 옮겨질 리전서버를 선택할 때 랜덤하게 선택합니다. 랜덤하게 리전서버를 선택하더라도 특정 리전서버에 리전이 몰리는 경우는 없습니다. 실행할 때마다 다른 밸런싱 결과를 얻을 수 있습니다.
  • Stochastic: 엄밀히 말하면 Stochastic은 룰이 아닙니다. HBase 기본 로드 밸런서인 StochasticLoadBalancer를 사용해서 테이블 단위로 밸런싱을 하는 방법입니다. 리전 무브로 인한 데이터 로컬리티 저하를 최소화 하면서 밸런스를 맞춰 줍니다. 그래서 서비스 중인 클러스터에서는 이 룰을 사용하는 것을 추천합니다.

3.1.3 리전 배치 복원

간혹 리전서버가 비정상적으로 종료되는 경우가 있습니다. 이런 경우 해당 리전서버에서 서비스 중이던 리전은 다른 리전서버로 흩어지게 됩니다. 죽었던 리전서버를 재시작하면 디폴트 로드 밸런서가 임의로 리전을 할당해 줍니다. 이렇게 되면 클러스터 전체의 데이터 로컬리티가 저하됩니다. 이때 hbase-manager를 사용하면 리전서버가 죽기 전 시점의 리전 배치로 되돌릴 수 있습니다.

리전의 배치 정보는 hbase:meta 테이블에 저장됩니다. meta 테이블은 최대 10개의 버전을 보관하고 있습니다. hbase-manager에서는 이 정보를 이용해서 특정 시점에 리전이 어떤 리전서버에서 서비스 중이었는지를 확인하고 그 리전서버로 다시 할당해 주고 있습니다.

3.2 Advanced Split

처음에 테이블을 생성하면서 바로 여러 리전으로 나누어 부하를 분산 시키려고 하거나, 사이즈가 큰 테이블을 마이그래이션 할 경우 프리스플릿(presplit)이 필요합니다. HBase Shell에서는 테이블을 처음 생성할 때 몇 가지 룰을 이용해서 프리스플릿을 할 수 있습니다. 하지만 이미 생성된 테이블에 대해서 동일한 룰을 적용해서 스플릿 할 수는 없습니다. 마이그래이션 할 소스 테이블과 동일한 스플릿키로 타겟 테이블을 스플릿 하는 방법도 쉘에 내장되어 있지는 않습니다.

hbase-manager에서는 이미 생성된 테이블에 대해서도 룰 기반으로 스플릿하는 기능을 제공합니다. 스플릿 과정에서 1개의 리전이 스플릿 되면, 새로 생긴 2개의 리전에 대해서 메이저 컴팩션(major compaction)이 발생합니다. hbase-manager는 메이저 컴팩션이 끝날 때까지 기다리며 순차적으로 리전을 스플릿합니다. 그래서 이미 테이블에 데이터가 많이 들어가 있는 경우에는 스플릿에 오랜 시간이 걸릴 수도 있습니다. 이런 경우에는 위에서 소개한 밸런싱 기능을 중간중간 실행해 주어서 메이저 컴팩션이 여러 리전서버에서 동시에 진행될 수 있도록 해주면 작업 시간을 단축시킬 수 있습니다.

또한 hbase-manager를 이용하면 마이그래이션할 소스 테이블의 스플릿 키를 파일로 저장하고, 그 정보를 바탕으로 타겟 테이블을 스플릿 해줄 수 있습니다. 이렇게 하면 마이그래이션 과정에서 발생하는 과도한 스플릿 및 그로 인한 메이저 컴팩션을 피할 수 있습니다. 이때 타겟 테이블의 hbase.hstore.compaction.max.size 속성까지 적절히 튜닝을 해 주어야 컴팩션 감소 효과를 제대로 얻을 수 있습니다.

3.3 Advanced Merge

어떤 경우에는 리전이 불필요하게 많이 쪼개진 경우도 있을 수 있습니다. 특히 Rowkey에 타임스탬프가 들어가 있고 동시에 TTL이 세팅된 테이블의 경우에는, 어느 정도 시간이 지나면 사이즈가 0인 리전이 다수 발생하게 됩니다. 리전이 과도하게 많아질 경우 좋지 않기 때문에(링크), 이런 경우 hbase-manager를 이용해서 사이즈가 0인 리전들을 머지(merge)를 할 수 있습니다.

현재 hbase-manager에는 사이즈가 0인 리전들만 머지 하는 기능이 있습니다. 리전 2개가 연속으로 사이즈 0일 경우에만 머지할 수도 있고, 연속 여부에 관계없이 사이즈 0인 리전을 머지할 수도 있습니다. 리전 머지도 스플릿과 마찬가지로 머지 후에 메이저 컴팩션이 발생합니다. 사이즈가 0인 리전들만 머지하는 이유는 머지로 인한 메이저 컴팩션이 클러스터에 주는 부하를 최소화 하기 위함 입니다. 특히 사이즈가 0인 리전 2개를 머지 할 경우 클러스터 성능에 미치는 영향은 거의 없습니다.

3.4 Advanced Major Compaction

메이저 컴팩션은 리전의 모든 스토어 파일을 읽어서 새로운 스토어 파일로 다시 기록하는 기능입니다. 이 과정에서 레코드의 물리적인 삭제, 데이터 로컬리티의 증가, 컬럼패밀리의 속성 변경 반영 등이 일어납니다. 그래서 운영자가 수동으로 메이저 컴팩션을 실행하는 경우가 있습니다. HBase Shell에서 메이저 컴팩션을 할 수 있는데, 테이블이나 리전 단위의 메이저 컴팩션을 실행할 수 있습니다.

hbase-manager를 이용하면 HBase Shell을 이용하는 것보다 정교하게 메이저 컴팩션을 할 수 있습니다. 리전서버, 테이블 등의 필터링 조건을 사용해서 메이저 컴팩션 범위를 좁힐 수 있습니다. 그리고 HBase 1.0 이상의 클러스터에서는 일정 수준 이하의 데이터 로컬리티를 가지는 리전들만 메이저 컴팩션 할 수도 있습니다.

4. hbase-snapshot: Table Snapshot Management

HBase에 저장된 데이터를 백업 및 복구하는 방법은 몇 가지가 있습니다. 그 중 카카오에서 메인으로 사용하고 있는 방법은 HBase 스냅샷(snapshot)입니다. 스냅샷은 백업 대상 데이터 사이즈가 크더라도 클러스터에 부하를 거의 주지 않고, 저장 공간도 스냅샷을 생성한 스토어 파일이 변경될 때만 소비하는 특성을 가지고 있습니다.

스냅샷은 세부적으로 DISABLED, FLUSH, SKIPFLUSH 세 가지 타입이 있습니다. DISABLED 스냅샷은 테이블이 disable 된 상태에서 만들어야 하는 것이라, 운영환경에서는 현실적으로 사용하기 어렵습니다. FLUSH 스냅샷은 테이블의 모든 리전의 멤스토어를 순차적으로 플러시 시켜서 스토어 파일을 추가로 생성하고 난 다음 스냅샷을 생성합니다. 하지만 모든 리전의 플러시가 동시에 이루어지는 것이 아니다 보니, 각 리전 별로 스냅샷 생성 시점이 수초에서 수분까지 다를 수 있습니다. 마지막은 SKIPFLUSH 스냅샷으로, 멤스토어 플러시를 생략하고 현재 존재하고 있는 스토어파일들만 가지고 스냅샷을 생성하는 방법입니다. 멤스토어는 기본적으로 1시간의 플러시 주기를 가지고 있기 때문에, 스냅샷에 최대 1시간 분량의 멤스토어에 있는 데이터가 누락 될 수 있다는 특성이 있습니다.

스냅샷 생성 시점 이후의 데이터 복구를 위해서는, WAL 아카이빙(archiving)도 병행해야 합니다. 아카이빙된 WAL은 WALPlayer을 이용해서 복구할 수 있습니다. WAL 보관 주기는 hbase.master.logcleaner.ttl을 세팅해서 조정할 수 있는데, 보통 스냅샷 생성 주기보다 1~2 시간 정도 길게 잡아 주면 됩니다. 그러나 쓰기가 많은 클러스터인 경우 아카이빙된 WAL의 사이즈가 매우 커질 수 있으므로, 클러스터의 워크로드 특성을 적절히 파악해서 세팅해야 합니다.

스냅샷 관리는 HBase Shell에서 할 수 있습니다. 하지만 생성, 복원, 조회, 삭제 등의 단위 기능만 가능하고, 대상 테이블 필터링, 유지할 스냅샷 갯수 설정, 스케줄링 등의 기능은 없습니다. 유료인 CM Enterprise Edition에서는 HBase 스냅샷 스케줄러 기능을 제공하고 있기는 하지만 CM Express Edition에서는 사용할 수가 없습니다. 그래서 스냅샷 생성 및 유지를 편리하게 하고자 hbase-snapshot을 만들었습니다.

hbase-snapshot에서는 정규표현식을 이용한 스냅샷 대상 테이블 설정, 스냅샷 제외 테이블 설정 등이 가능합니다. 또한 일정한 갯수의 스냅샷만 보관하고, 그 이상의 스냅샷은 오래된 순서대로 삭제하는 기능도 있습니다. 그리고 SKIPFLUSH를 적용할 대상 테이블도 세팅할 수 있습니다. hbase-snapshot에도 자체적인 스케줄링 기능은 없기 때문에, crontab을 이용해서 hbase-snapshot 커맨드를 각 클러스터 별로 적절히 스케줄링해 주어야 합니다.

5. 맺음말

hbase-tools는 어떻게 하면 HBase 클러스터를 사용자에 미치는 영향을 최소화 하면서 매끄럽게 운영할 수 있을까? 하는 고민을 해결하는 과정에서 만들어졌습니다. 앞으로도 이런 고민은 계속 될 것이고, 그에 따라 hbase-tools에 대한 기능 추가 및 개선도 계속될 것입니다.

이 글과 hbase-tools가 HBase 이용자들에게 작으나마 도움이 되었기를 바라는 마음을 전하면서, 글을 마무리 하겠습니다. 감사합니다.

참고: 이 글은 툴의 기능에 대해서 개념적인 소개에 대해서만 다루고 있습니다. 모듈의 구조와 툴의 구체적인 사용방법은 Introduction And Use Cases 문서를 참고하세요.

terence.yoo's profile image

terence.yoo

2016-03-24 14:30

Read more posts by this author