대규모 질의를 위한 HiveServer2 고가용성(HA) 아키텍처 구축 (with HAProxy)
과거 당사의 데어터 분석 포털 빅데이터 모니터링 플랫폼에서는, 사용자가 GUI 환경의 Query Editor 창에서 날린 SQL을 곧바로 하둡 백엔드로 던져 결과를 가져오는 기능이 주력이었습니다.
전사의 마케터와 데이터 분석가가 동시에 플랫폼에 접속해 무거운 Hive 쿼리를 던지게 되면, 단일 노드에 떠 있는 HiveServer2(HS2) 서비스 하나로는 커맨드 파싱과 세션 유지를 도저히 버텨 낼 수 없어 데몬 서버 자체가 터져버리는 일(OOM: Out of Memory)이 잦았습니다. 이를 막기 위해 플랫폼 서버와 여러 대의 하이브 노드 사이에 물리적인 하드웨어 L4(Load Balancer) 스위치를 두는 것이 돈이 많은 은행권의 관행이었지만, 가난한(?) 사내 클러스터나 중소 프로젝트에서는 HAProxy라는 훌륭한 오픈소스 리버스 프록시(Reverse Proxy)를 사용하여 소프트웨어 방식의 고가용성(High Availability, HA) 묶음을 만들어 제공했습니다.
1. HAProxy 설치 및 밸런싱 모드 설정
우선 플랫폼가 떠 있는 마스터 엣지 서버나 별도의 분산 전용 노드에 haproxy 패키지를 설치합니다.
$ yum install haproxy
$ vi /etc/haproxy/haproxy.cfg설정 파일의 최하단 쯤에 사용자가 진입할 껍데기 포트(Front-end)와 부하를 넘겨줄 진짜 HiveServer2의 물리 서버들(Back-end)을 묶어줍니다. 이때 분산 알고리즘이나 타임아웃을 넉넉하게 주어야 배치(Batch) 성 쿼리가 길게 통신되어도 소켓이 끊기지 않습니다.
listen hiveserver2 :10001
log 127.0.0.1:514 local2
mode tcp # Hive JDBC 연결은 HTTP가 아닌 완전 TCP 기반
option tcplog
balance source # 라우팅 밸런싱 방법 지정 (출발지 IP 기반 라운드로빈 유지)
timeout client 5m # 무거운 쿼리가 돌 것을 감안하여 5분 유지
timeout server 5m
# 실제 백에 떠 있는 HiveServer2 인스턴스 타겟들 지정
server hiveserver2_1 cdh1.exem.dev:10000
server hiveserver2_2 cdh3.exem.dev:100002. 장애 추적을 위한 rsyslog 로그 바인딩
L4 프록시는 중간에서 길만 터주는 역할이므로 어디로 패킷이 넘어갔는지 반드시 궤적을 남겨야 나중에 “쿼리가 죽었어요!”라는 고객사 클레임에 방어할 수 있습니다. 위에서 설정한 local2 이벤트 스트림을 OS 로그 포맷으로 파일로 내리기 위해 설정합니다.
$ vi /etc/rsyslog.d/haproxy.conf
# 내용물로 단 한줄 추가:
# local2.* /var/log/haproxy.log
# 로그 서비스 재기동
$ service rsyslog restart3. Cloudera Manager의 생태계에 편입시키기 (CDH)
단순히 데몬만 올린다고 끝이 아닙니다. CDH 에코시스템 안에 서식하는 Hue(휴), Impala, 그리고 각종 관리 UI들도 이 L4 묶음을 바라보도록 튜닝을 해줘야 합니다.
- Cloudera Manager(CM) 우상단 메뉴에서 Hive 서비스 파트로 진입한 후, 노드를 클릭해 물리 서버 장비 두 대 이상에
HiveServer2역할을 추가 설치합니다. - Hive > 구성 > 검색창에 “Load Balancer” 기입
- 하이브 밸런싱 호스트 입력란에 방금 구축한
cdh1.exem.dev:10001(HAProxy 호스트:포트) 도메인을 잡아주고 전체 재기동을 때립니다.
이제 당사 플랫폼의 JDBC 드라이버 커넥션 풀(Connection Pool)의 타겟 주소를 이 고가용성 포트로만 설정해주면, 하나의 물리 노드가 디스크가 나가 죽어버리더라도 나머지 노드가 안정적으로 거대한 조회 쿼리의 부담을 묵묵하게 견뎌내는 강인한 아키텍처가 완성됩니다.
(여담: 운영 중에 L4의 상태를 브라우저로 보고 싶다면 HAProxy stats 설정(stats auth admin:admin)을 추가해 GUI 대시보드를 띄울 수도 있습니다.)