중요한 설정

중요한 설정 (The Important Configurations)

HBase 클러스터를 운영할 때 특히 신경 써야 할 핵심 설정들을 정리한 페이지예요. 필수 설정과 권장 설정으로 나뉘며, 각 설정이 어떤 상황에서 왜 중요한지 설명해요.

출처: 문서

본문

필수 설정 (Required Configurations)

os와 hadoop 섹션을 검토하세요.

대형 클러스터 설정 (Big Cluster Configurations)

region이 많은 클러스터라면 Master가 시작된 직후 RegionServer 하나가 먼저 체크인하고 나머지 RegionServer들이 뒤처지는 상황이 발생할 수 있어요. 가장 먼저 체크인하는 서버에 모든 region이 할당되는데 이는 최적이 아니에요. 위 시나리오를 방지하려면 hbase.master.wait.on.regionservers.mintostart 속성을 기본값 1에서 올리세요. 자세한 내용은 HBASE-6389 Modify the conditions to ensure that Master waits for sufficient number of Region Servers before starting region assignments를 참고하세요.

ZooKeeper 설정 (ZooKeeper Configuration)

zookeeper.session.timeout

기본 타임아웃은 90초(밀리초로 지정)예요. 즉 서버가 크래시하면 Master가 크래시를 알아차리고 복구를 시작하기까지 90초가 걸린다는 뜻이에요. Master가 실패를 더 빨리 알아차리도록 타임아웃을 1분이나 그 이하로 낮춰야 할 수도 있어요. 이 값을 변경하기 전에 JVM 가비지 컬렉션 설정을 확실히 제어하고 있는지 확인하세요. 그렇지 않으면 ZooKeeper 세션 타임아웃을 넘어가는 긴 가비지 컬렉션이 RegionServer를 죽일 거예요.(이것이 괜찮을 수도 있어요 — RegionServer가 오랫동안 GC 상태에 있다면 복구를 시작하길 원할 테니까요).

이 설정을 변경하려면 hbase-site.xml을 편집하고, 변경된 파일을 클러스터 전체에 복사한 뒤 재시작하세요.

우리는 대규모 import 중에 RegionServer가 왜 죽었는지 묻는 메일링 리스트 질문에 답해야 하는 것을 피하기 위해 이 값을 높게 설정했어요. 보통 원인은 JVM이 튜닝되지 않아 긴 GC pause를 겪는 것입니다. 우리 생각은 사용자가 HBase에 익숙해지는 동안 모든 세세한 부분을 알 필요를 덜어주자는 것이었어요. 나중에 자신감이 생기면 이런 설정을 직접 만질 수 있게 되죠.

ZooKeeper 인스턴스 수 (Number of ZooKeeper Instances)

zookeeper를 참고하세요.

HDFS 설정 (HDFS Configurations)

dfs.datanode.failed.volumes.tolerated

이것은 hdfs-default.xml 설명에서 나온 "...DataNode가 서비스 제공을 중지하기 전에 실패하도록 허용된 볼륨 수예요. 기본적으로 어떤 볼륨 실패든 datanode를 종료시켜요."입니다. 사용 가능한 디스크 양의 절반 정도로 설정하고 싶을 거예요.

hbase.regionserver.handler.count

이 설정은 사용자 테이블에 대한 들어오는 요청에 응답하기 위해 열어 두는 스레드 수를 정의해요. 경험상 요청당 페이로드가 MB에 근접하면(큰 puts, 큰 캐시를 사용하는 scans) 이 수를 낮게 유지하고, 페이로드가 작으면(get, 작은 puts, ICVs, deletes) 높게 유지하세요. 진행 중인 쿼리의 총 크기는 hbase.ipc.server.max.callqueue.size 설정으로 제한돼요.

페이라로드가 작고 들어오는 클라이언트 수가 최대라면 그 수로 안전하게 설정할 수 있어요. 전형적인 예는 puts가 보통 버퍼링되지 않고 대부분의 연산이 gets인 웹사이트를 서빙하는 클러스터예요.

이 설정을 높게 유지하는 것이 위험한 이유는 region server에서 현재 발생 중인 모든 puts의 총 크기가 메모리에 너무 많은 압박을 주거나, 심지어 OutOfMemoryError를 유발할 수 있기 때문이에요. 낮은 메모리에서 실행되는 RegionServer는 JVM의 가비지 컬렉터가 더 자주 실행되도록 만들어 GC pause가 눈에 띄는 지점까지 이르게 해요(이유는 모든 요청 페이로드를 유지하는 데 사용되는 메모리를 가비지 컬렉터가 아무리 노력해도 버릴 수 없기 때문이에요). 잠시 후, 그 RegionServer에 도달하는 모든 요청이 더 오래 걸리므로 전체 클러스터 처리량에 영향을 주고, 이는 문제를 더욱 악화시켜요.

핸들러가 너무 적은지 많은지는 개별 RegionServer에서 rpc.logging을 켠 뒤 로그를 tail해서 감을 잡을 수 있어요(Queued requests는 메모리를 소비해요).

대용량 메모리 머신 설정 (Configuration for large memory machines)

HBase는 사람들이 테스트하고 싶어할 거의 모든 머신 유형에서 동작하는 합리적이고 보수적인 설정과 함께 배포돼요. 더 큰 머신 — 8G 이상의 힙 — 이 있다면 다음 설정 옵션이 도움이 될 수 있어요. TODO.

압축 (Compression)

ColumnFamily 압축을 활성화하는 것을 고려해야 해요. 거의 마찰이 없고 대부분의 경우 StoreFile 크기를 줄여 I/O를 줄임으로써 성능을 높이는 여러 옵션이 있어요.

자세한 내용은 compression을 참고하세요.

WAL 파일의 크기와 수 설정 (Configuring the size and number of WAL files)

HBase는 WAL을 사용해 RS 실패 시 디스크로 flush되지 않은 memstore 데이터를 복구해요. 이 WAL 파일은 HDFS 블록보다 약간 작게 구성해야 해요(기본적으로 HDFS 블록은 64Mb이고 WAL 파일은 약 60Mb예요).

HBase는 또한 복구 중에 재생해야 하는 데이터가 너무 많지 않도록 보장하도록 설계된 WAL 파일 수 제한이 있어요. 이 제한은 모든 필수 데이터가 들어갈 수 있도록 memstore 설정에 따라 설정해야 해요. 적어도 그만큼의 데이터를 저장할 수 있을 만큼 충분한 WAL 파일을 할당하는 것이 권장돼요(모든 memstore가 거의 가득 찼을 때). 예를 들어 16Gb RS 힙, 기본 memstore 설정(0.4), 기본 WAL 파일 크기(~60Mb)라면 16Gb*0.4/60으로 WAL 파일 수의 출발점은 약 109예요. 그러나 모든 memstore가 항상 가득 차 있을 것으로 기대되지는 않으므로 더 적은 WAL 파일을 할당할 수 있어요.

관리형 분할 (Managed Splitting)

HBase는 일반적으로 hbase-default.xml과 hbase-site.xml 설정 파일의 설정에 따라 region 분할을 처리해요. 중요한 설정으로는 hbase.regionserver.region.split.policy, hbase.hregion.max.filesize, hbase.regionserver.regionSplitLimit가 있어요. 분할에 대한 단순한 관점은 region이 hbase.hregion.max.filesize로 커지면 분할된다는 것이에요. 대부분의 사용 패턴에서는 자동 분할을 사용해야 해요. 수동 region 분할에 대한 자세한 내용은 manual region splitting decisions을 참고하세요.

HBase가 region을 자동으로 분할하도록 두는 대신, 분할을 직접 관리하도록 선택할 수 있어요. 키스페이스를 잘 알고 있다면 수동 분할이 동작하고, 그렇지 않다면 HBase가 어디를 분할할지 알아서 정하도록 두세요. 수동 분할은 부하 상황에서 region 생성·이동을 완화할 수 있어요. 또한 region 경계를 알 수 있고 불변으로 만듭니다(region 분할을 비활성화한다면). 수동 분할을 사용하면 네트워크 I/O 로드를 분산시키기 위해 단계적인 시간 기반 major compaction을 수행하기 더 쉬워요.

자동 분할 비활성화 (Disable Automatic Splitting)

자동 분할을 비활성화하려면 클러스터 설정이나 테이블 설정에서 region split policy를 org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy로 설정할 수 있어요.

문제를 진단하거나 빠른 데이터 증가 기간 동안 자동 분할을 비활성화했다면, 상황이 안정화되면 다시 활성화하는 것이 권장돼요. region 분할을 직접 관리하는 잠재적 이점은 이견이 없지 않아요.

최적의 사전 분할(pre-split) region 수 결정 (Determine the Optimal Number of Pre-Split Regions)

최적의 사전 분할 region 수는 애플리케이션과 환경에 따라 달라요. 서버당 10개의 사전 분할 region으로 시작하고 시간이 지나면서 데이터가 자라는 것을 지켜보는 것이 좋은 경험칙이에요. 너무 적은 region 쪽으로 오류를 범하고 나중에 롤링 분할을 수행하는 게 낫습니다. 최적 region 수는 region에서 가장 큰 StoreFile에 따라 달라져요. 데이터 양이 늘면 가장 큰 StoreFile의 크기도 시간이 지나면서 커져요. 목표는 가장 큰 region이 컴팩션 선택 알고리즘이 예정된 major compaction 중에만 컴팩트하도록 딱 크게 하는 것이에요. 그렇지 않으면 동시에 컴팩션 중인 많은 수의 region으로 컴팩션 스톰(compaction storm)이 발생하기 쉬워요. 컴팩션 스톰을 유발하는 것은 수동 분할 결정이 아니라 데이터 증가라는 점을 이해하는 것이 중요해요.

region이 너무 많은 큰 region으로 분할된다면 HConstants.MAJOR_COMPACTION_PERIOD를 구성해 major compaction 간격을 늘릴 수 있어요. org.apache.hadoop.hbase.util.RegionSplitter 유틸리티는 또한 모든 region의 네트워크 I/O 안전한 롤링 분할을 제공해요.

관리형 컴팩션 (Managed Compactions)

기본적으로 major compactions는 7일 기간에 한 번 실행되도록 예정돼요.

major compaction이 정확히 언제, 얼마나 자주 실행되는지 제어해야 한다면 관리형 major compaction을 비활성화할 수 있어요. 자세한 내용은 compaction.parameters 표의 hbase.hregion.majorcompaction 항목을 참고하세요.

Major compactions는 StoreFile 정리에 절대적으로 필요해요. 그것들을 통째로 비활성화하지 마세요. HBase shell이나 Admin API로 major compactions를 수동으로 실행할 수 있어요.

컴팩션과 컴팩션 파일 선택 프로세스에 대한 자세한 내용은 compaction을 참고하세요.

추측 실행 (Speculative Execution)

MapReduce 태스크의 추측 실행(Speculative Execution)은 기본적으로 켜져 있으며, HBase 클러스터에서는 특정 사례가 필요하지 않다면 시스템 수준에서 추측 실행을 끄는 것이 일반적으로 권장돼요. 특정 사례에서는 작업별로 구성할 수 있어요. mapreduce.map.speculative와 mapreduce.reduce.speculative 속성을 false로 설정하세요.

기타 설정 (Other Configurations)

밸런서 (Balancer)

밸런서는 클러스터의 region을 재분배하기 위해 master에서 실행되는 주기적 연산이에요. hbase.balancer.period로 구성되며 기본값은 300000(5분)이에요.

LoadBalancer에 대한 자세한 내용은 master.processes.loadbalancer를 참고하세요.

블록캐시 비활성화 (Disabling Blockcache)

블록 캐시를 끄지 마세요(hfile.block.cache.size를 0으로 설정하면 됩니다). 현재는 그렇게 하면 RegionServer가 모든 시간을 HFile 인덱스를 계속해서 로드하는 데 쓰게 되므로 잘 처리하지 못해요. 워킹 셋이 블록 캐시가 도움이 되지 않을 정도라면, 적어도 HFile 인덱스가 캐시에 남도록 블록 캐시 크기를 잡으세요(RegionServer UI를 조사하면 필요한 크기를 대략 알 수 있어요. 웹페이지 상단 근처에 인덱스 블록 크기가 표시될 거예요).

Nagle 또는 작은 패키지 문제 (Nagle's or the small package problem)

HBase에 대한 연산에서 약 40ms 정도의 큰 간헐적 지연이 보이면 Nagle's 설정을 시도해 보세요. 예를 들어 사용자 메일링 리스트 스레드 Inconsistent scan performance with caching set to 1과 그 안에서 인용된 issue를 참고하세요. notcpdelay를 설정하면 스캔 속도가 개선됐어요. 또한 HBASE-7008 Set scanner caching to a better default 꼬리의 그래프를 볼 수도 있어요. 우리의 Lars Hofhansl은 Nagle을 켜고 끈 상태로 다양한 데이터 크기를 시도하며 그 효과를 측정했어요.

더 나은 평균 복구 시간 (MTTR) (Better Mean Time to Recover (MTTR))

이 섹션은 실패 후 서버가 더 빨리 돌아오게 하는 설정에 관한 것이에요. 간단한 소개는 Deveraj Das와 Nicolas Liochon의 블로그 글 Introduction to HBase Mean Time to Recover (MTTR)를 참고하세요.

이슈 HBASE-8354 forces Namenode into loop with lease recovery requests는 지저분하지만 낮은 타임아웃과 더 빠른 복구 방법에 대한 좋은 논의가 끝부분에 많아요. HDFS에 추가된 수정 사항도 인용돼 있어요. Varun Sharma의 댓글을 읽어보세요. 아래 제안된 설정은 Varun의 제안을 정제하고 테스트한 것이에요. HBase MTTR을 돕는 그가 언급하고 그가 HDFS에 직접 추가한 수정 사항(HDFS-3703, HDFS-3712, HDFS-4791 — Hadoop 2에는 확실히 있고, 후기 Hadoop 1에는 일부 있음)이 있도록 후기 버전 HDFS에서 실행 중인지 확인하세요. RegionServer에 다음을 설정하세요.

hbase.lease.recovery.dfs.timeout 23000 How much time we allow elapse between calls to recover lease. Should be larger than the dfs timeout. dfs.client.socket-timeout 10000 Down the DFS timeout from 60 to 10 seconds.

그리고 NameNode/DataNode 쪽에서 HDFS-3703, HDFS-3912에서 도입된 'staleness'를 활성화하려면 다음을 설정하세요.

dfs.client.socket-timeout 10000 Down the DFS timeout from 60 to 10 seconds. dfs.datanode.socket.write.timeout 10000 Down the DFS timeout from 8 * 60 to 10 seconds. ipc.client.connect.timeout 3000 Down from 60 seconds to 3. ipc.client.connect.max.retries.on.timeouts 2 Down from 45 seconds to 3 (2 == 3 retries). dfs.namenode.avoid.read.stale.datanode true Enable stale state in hdfs dfs.namenode.stale.datanode.interval 20000 Down from default 30 seconds dfs.namenode.avoid.write.stale.datanode true Enable stale state in hdfs

JMX

JMX(Java Management Extensions)는 Java VM을 모니터링·관리할 수 있게 해주는 내장 계측을 제공해요. 원격 시스템에서 모니터링·관리를 활성화하려면 Java VM을 시작할 때 시스템 속성 com.sun.management.jmxremote.port(JMX RMI 연결을 활성화할 포트 번호)를 설정해야 해요. 자세한 내용은 공식 문서를 참고하세요. 역사적으로 위에서 언급한 포트 외에 JMX는 추가로 두 개의 임의 TCP 리슨 포트를 열어 포트 충돌 문제를 일으킬 수 있었어요(자세한 내용은 HBASE-10289 참고).

대안으로 HBase가 제공하는 coprocessor 기반 JMX 구현을 사용할 수 있어요. 활성화하려면 hbase-site.xml에 아래 속성을 추가하세요.

hbase.coprocessor.regionserver.classes org.apache.hadoop.hbase.JMXListener

동시에 Java VM에 com.sun.management.jmxremote.port를 설정하지 마세요.

현재 Master와 RegionServer Java VM을 지원해요. 기본적으로 JMX는 TCP 포트 10102에서 리슨하며, 아래 속성들로 포트를 추가로 구성할 수 있어요.

regionserver.rmi.registry.port 61130 regionserver.rmi.connector.port 61140

대부분의 경우 registry 포트는 connector 포트와 공유할 수 있으므로 regionserver.rmi.registry.port만 구성하면 돼요. 그러나 SSL 통신을 사용하려면 두 포트를 다른 값으로 구성해야 해요.

기본적으로 비밀번호 인증과 SSL 통신은 비활성화돼 있어요. 비밀번호 인증을 활성화하려면 hbase-env.sh를 다음과 같이 업데이트하세요.

export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=your_password_file
-Dcom.sun.management.jmxremote.access.file=your_access_file"

export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE " export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE "

예시 비밀번호/접근 파일은 $JRE_HOME/lib/management 아래에서 확인하세요.

비밀번호 인증과 함께 SSL 통신을 활성화하려면 다음 단계를 따르세요.

#1. generate a key pair, stored in myKeyStore keytool -genkey -alias jconsole -keystore myKeyStore

#2. export it to file jconsole.cert keytool -export -alias jconsole -keystore myKeyStore -file jconsole.cert

#3. copy jconsole.cert to jconsole client machine, import it to jconsoleKeyStore keytool -import -alias jconsole -keystore jconsoleKeyStore -file jconsole.cert

그런 다음 hbase-env.sh를 다음과 같이 업데이트하세요.

export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.ssl=true
-Djavax.net.ssl.keyStore=/home/tianq/myKeyStore
-Djavax.net.ssl.keyStorePassword=your_password_in_step_1
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=your_password file
-Dcom.sun.management.jmxremote.access.file=your_access_file"

export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE " export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE "

마지막으로 클라이언트에서 키 스토어를 사용해 jconsole을 시작하세요.

jconsole -J-Djavax.net.ssl.trustStore=/home/tianq/jconsoleKeyStore

Master에서 HBase JMX 구현을 활성화하려면 hbase-site.xml에 아래 속성도 추가해야 해요.

hbase.coprocessor.master.classes org.apache.hadoop.hbase.JMXListener

포트 구성에 해당하는 속성은 master.rmi.registry.port(기본값 10101)와 master.rmi.connector.port(기본값 registry.port와 동일)예요.

더 알아보기 (Learn more)