단일 클러스터에서 여러 워크로드 실행
단일 클러스터에서 여러 워크로드 실행 (Running Multiple Workloads On a Single Cluster)
하나의 HBase 클러스터에서 여러 워크로드를 관리하는 메커니즘을 설명하는 페이지예요. 쿼터(quota), 요청 큐, 다중 유형 큐를 통해 리소스 할당을 제어할 수 있습니다.
출처: 문서
본문
HBase는 여러 워크로드를 처리하는 클러스터의 성능을 관리하기 위해 다음 메커니즘을 제공해요.
- Quotas
- Request Queues
- Multiple-Typed Queues
쿼터 (Quotas)
HBASE-11598은 RPC 쿼터를 도입했는데, 다음 한도에 따라 요청을 조절(throttle)할 수 있게 해줘요.
- 주어진 시간 프레임 내 요청의 수나 크기(읽기, 쓰기, 또는 읽기+쓰기)
- 네임스페이스에서 허용되는 테이블 수
이 한도는 지정된 사용자, 테이블, 또는 네임스페이스에 대해 강제할 수 있어요.
쿼터 활성화 (Enabling Quotas)
쿼터는 기본적으로 비활성화돼 있어요. 기능을 활성화하려면 모든 클러스터 노드의 hbase-site.xml 파일에서 hbase.quota.enabled 속성을 true로 설정하세요.
일반 쿼터 구문 (General Quota Syntax)
- THROTTLE_TYPE은 READ, WRITE, 또는 기본 유형(읽기+쓰기)으로 표현할 수 있어요.
- 시간 프레임은
sec,min,hour,day단위로 표현할 수 있어요. - 요청 크기는
B(바이트),K(킬로바이트),M(메가바이트),G(기가바이트),T(테라바이트),P(페타바이트) 단위로 표현할 수 있어요. - 요청 수는 정수 뒤에
req문자열을 붙여 표현해요. - 시간 관련 한도는 req/time 또는 size/time으로 표현해요. 예:
10req/day또는100P/hour. - 테이블 또는 region의 수는 정수로 표현돼요.
요청 쿼터 설정 (Setting Request Quotas)
쿼터 규칙을 미리 설정하거나 런타임에 throttle을 변경할 수 있어요. 변경 사항은 쿼터 새로고침 주기가 만료된 후 전파돼요. 이 만료 기간은 기본 5분이에요. 변경하려면 hbase-site.xml의 hbase.quota.refresh.period 속성을 수정하세요. 이 속성은 밀리초로 표현되며 기본값은 300000이에요.
Limit user u1 to 10 requests per second
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10req/sec'
Limit user u1 to 10 read requests per second
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', LIMIT => '10req/sec'
Limit user u1 to 10 M per day everywhere
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10M/day'
Limit user u1 to 10 M write size per sec
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => WRITE, USER => 'u1', LIMIT => '10M/sec'
Limit user u1 to 5k per minute on table t2
hbase> set_quota TYPE => THROTTLE, USER => 'u1', TABLE => 't2', LIMIT => '5K/min'
Limit user u1 to 10 read requests per sec on table t2
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', TABLE => 't2', LIMIT => '10req/sec'
Remove an existing limit from user u1 on namespace ns2
hbase> set_quota TYPE => THROTTLE, USER => 'u1', NAMESPACE => 'ns2', LIMIT => NONE
Limit all users to 10 requests per hour on namespace ns1
hbase> set_quota TYPE => THROTTLE, NAMESPACE => 'ns1', LIMIT => '10req/hour'
Limit all users to 10 T per hour on table t1
hbase> set_quota TYPE => THROTTLE, TABLE => 't1', LIMIT => '10T/hour'
Remove all existing limits from user u1
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => NONE
List all quotas for user u1 in namespace ns2
hbase> list_quotas USER => 'u1, NAMESPACE => 'ns2'
List all quotas for namespace ns2
hbase> list_quotas NAMESPACE => 'ns2'
List all quotas for table t1
hbase> list_quotas TABLE => 't1'
list all quotas
hbase> list_quotas
또한 GLOBAL_BYPASS 속성을 적용해 전역 한도를 두고 특정 사용자나 테이블을 그 한도에서 제외할 수 있어요.
hbase> set_quota NAMESPACE => 'ns1', LIMIT => '100req/min' # a per-namespace request limit hbase> set_quota USER => 'u1', GLOBAL_BYPASS => true # user u1 is not affected by the limit
RPC 스로틀링 활성화·비활성화·확인 (Enabling, Disabling, and Checking RPC Throttling)
HBase는 런타임에 RPC 스로틀링을 제어하는 셸 명령을 제공해요. 스로틀링이 비활성화되면 HBase는 어떤 요청 스로틀링도 적용하지 않아요. 일시적인 비스로틀링(unthrottled) 운영이 필요한 프로덕션 환경에서 유용할 수 있어요.
다음 HBase 셸 명령을 사용할 수 있어요.
Enable RPC throttling
hbase> enable_rpc_throttle
Disable RPC throttling
hbase> disable_rpc_throttle
Check whether RPC throttling is enabled
hbase> rpc_throttle_enabled
enable_rpc_throttle과 disable_rpc_throttle은 이전 RPC 스로틀링 상태를 불리언 값으로 반환해요. rpc_throttle_enabled는 현재 상태를 반환해요.
쿼터가 구성되지 않으면 RPC 스로틀링이 적용되지 않으며, 스로틀링을 활성화·비활성화해도 항상 false를 반환해요.
네임스페이스 쿼터 설정 (Setting Namespace Quotas)
네임스페이스 생성 시 또는 기존 네임스페이스를 alter할 때 네임스페이스에 hbase.namespace.quota.maxtables 속성을 설정해 주어진 네임스페이스에서 허용되는 최대 테이블 또는 region 수를 지정할 수 있어요.
네임스페이스당 테이블 제한 (Limiting Tables Per Namespace)
Create a namespace with a max of 5 tables
hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxtables'=>'5'}
Alter an existing namespace to have a max of 8 tables
hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxtables'=>'8'}
Show quota information for a namespace
hbase> describe_namespace 'ns2'
Alter an existing namespace to remove a quota
hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=>'hbase.namespace.quota.maxtables'}
네임스페이스당 region 제한 (Limiting Regions Per Namespace)
Create a namespace with a max of 10 regions
hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxregions'=>'10'}
Show quota information for a namespace
hbase> describe_namespace 'ns1'
Alter an existing namespace to have a max of 20 tables
hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxregions'=>'20'}
Alter an existing namespace to remove a quota
hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=> 'hbase.namespace.quota.maxregions'}
요청 큐 (Request Queues)
스로틀링 정책이 구성되지 않으면 RegionServer가 여러 요청을 받을 때, 그것들은 이제 빈 실행 슬롯을 기다리는 큐에 배치돼요(HBASE-6721). 가장 단순한 큐는 FIFO 큐로, 각 요청은 큐의 모든 이전 요청이 끝날 때까지 기다린 뒤 실행돼요. 빠른 또는 인터랙티브 쿼리가 큰 요청 뒤에 갇힐 수 있어요.
요청이 얼마나 걸릴지 짐작할 수 있다면, 긴 요청을 큐 끝으로 밀고 짧은 요청이 이를 선점하도록 허용해 요청 순서를 바꿀 수 있어요. 결국 큰 요청은 여전히 실행해야 하고 그 뒤의 새 요청에 우선순위를 줘야 해요. 짧은 요청이 더 새것이므로 결과가 끔찍하지는 않지만, 큰 요청을 여러 개의 더 작은 것으로 쪼갤 수 있는 메커니즘과 비교하면 여전히 최적이 아니에요.
HBASE-10993은 오래 실행되는 스캐너를 저우선순위화(deprioritize)하는 그러한 시스템을 도입해요. 큐에는 fifo와 deadline 두 가지 유형이 있어요. 사용할 큐 유형을 구성하려면 hbase-site.xml에서 hbase.ipc.server.callqueue.type 속성을 구성하세요. 각 요청이 얼마나 걸릴지 추정할 방법이 없으므로 저우선순위화는 스캔에만 영향을 주고, 스캔 요청이 만든 "next" 호출 수에 기반해요. 전체 테이블 스캔을 할 때 작업이 인터랙티브일 가능성이 낮다고 가정하므로, 동시 요청이 있으면 hbase.ipc.server.queue.max.call.delay 속성으로 튜닝할 수 있는 한도까지 오래 실행되는 스캔을 지연시킬 수 있어요. 지연의 기울기는 (numNextCall * weight)의 단순 제곱근으로 계산되며, 여기서 weight는 hbase.ipc.server.scan.vtime.weight 속성으로 구성할 수 있어요.
다중 유형 큐 (Multiple-Typed Queues)
지정된 수의 전용 핸들러와 큐를 구성해 여러 종류의 요청에 우선순위를 주거나 저우선순위를 줄 수 있어요. 스캔 요청을 단일 핸들러가 있는 단일 큐에 분리하고, 다른 모든 사용 가능한 큐가 짧은 Get 요청을 처리할 수 있어요.
정적 튜닝 옵션을 사용해 워크로드 유형에 따라 IPC 큐와 핸들러를 조정할 수 있어요. 이 접근은 궁극적으로 런타임에 설정을 변경하고 부하에 따라 값을 동적으로 조정할 수 있게 하는 중간의 첫 단계예요.
다중 큐 (Multiple Queues)
경합을 피하고 여러 종류의 요청을 분리하려면 hbase.ipc.server.callqueue.handler.factor 속성을 구성하세요. 이 속성은 큐 수를 늘리고 얼마나 많은 핸들러가 같은 큐를 공유할 수 있는지 제어할 수 있게 해줘요. 관리자가 큐 수를 늘리고 몇 개의 핸들러가 같은 큐를 공유할지 결정하게 해줘요.
큐를 더 많이 사용하면 큐에 태스크를 추가하거나 큐에서 선택할 때 경합이 줄어들어요. 핸들러당 하나의 큐를 구성할 수도 있어요. 트레이드오프는 일부 큐에 오래 실행되는 태스크가 있으면, 대기 중인 태스크가 있는 다른 큐에서 훔치는 대신 핸들러가 그 큐에서 실행되기를 기다려야 할 수 있다는 것이에요.
읽기·쓰기 큐 (Read and Write Queues)
다중 큐로 이제 읽기와 쓰기 요청을 나눌 수 있고, 한 유형에 더 많은 우선순위(더 많은 큐)를 줄 수 있어요. hbase.ipc.server.callqueue.read.ratio 속성을 사용해 더 많은 읽기 또는 더 많은 쓰기를 서빙하도록 선택하세요.
Get·Scan 큐 (Get and Scan Queues)
읽기/쓰기 분할과 유사하게, hbase.ipc.server.callqueue.scan.ratio 속성을 튜닝해 gets와 scans를 분할해 gets나 scans에 더 많은 우선순위를 줄 수 있어요. scan 비율 0.1은 들어오는 gets에 더 많은 큐/핸들러를 주므로 더 많은 gets가 동시에 처리되고 더 적은 scans가 동시에 실행될 수 있어요. 0.9 값은 scans에 더 많은 큐/핸들러를 주므로 실행되는 scans 수가 늘어나고 gets 수가 줄어들어요.
공간 쿼터 (Space Quotas)
HBASE-16961은 HBase가 활용할 수 있는 새 유형의 쿼터인 파일시스템 쿼터를 도입해요. 이러한 "공간" 쿼터는 HBase 네임스페이스와 테이블이 소비할 수 있는 파일시스템의 공간 양을 제한해요. 악의적이든 무지하든 사용자가 HBase에 데이터를 쓸 능력이 있다면, 충분한 시간이 지나면 그 사용자는 사용 가능한 모든 공간을 소비해 사실상 HBase(또는 더 나쁘게는 HDFS)를 크래시시킬 수 있어요. 파일시스템 공간이 없으면 HBase는 더 이상 write-ahead log에 데이터를 생성/동기화할 수 없어 크래시돼요.
이 기능은 테이블이나 네임스페이스의 크기에 한도를 설정할 수 있게 해줘요. 네임스페이스에 공간 쿼터가 설정되면 그 쿼터의 한도는 그 네임스페이스의 모든 테이블 사용량의 합에 적용돼요. 쿼터가 있는 테이블이 쿼터가 있는 네임스페이스에 존재하면 테이블 쿼터가 네임스페이스 쿼터보다 우선해요. 이는 테이블 모음에 큰 한도를 두되, 그 모음의 단일 테이블에는 세밀한 한도를 설정할 수 있는 시나리오를 허용해요.
기존 set_quota와 list_quota HBase 셸 명령으로 공간 쿼터와 상호작용할 수 있어요. 공간 쿼터는 TYPE이 SPACE이고 LIMIT과 POLICY 속성을 가져요. LIMIT은 쿼터 대상(예: 테이블 또는 네임스페이스)이 소비할 수 있는 파일시스템의 공간 양을 나타내는 문자열이에요. 예를 들어 LIMIT의 유효한 값은 '10G', '2T', '256M'이에요. POLICY는 쿼터 대상의 사용량이 LIMIT을 초과할 때 HBase가 취할 조치를 나타내요. 유효한 POLICY 값은 다음과 같아요.
NO_INSERTS— 새 데이터를 쓸 수 없음(예:Put,Increment,Append).NO_WRITES—NO_INSERTS와 같지만Deletes도 허용되지 않음.NO_WRITES_COMPACTIONS—NO_WRITES와 같지만 compactions도 허용되지 않음. 이 정책은 사용자 제출 컴팩션만 방지해요. 시스템은 여전히 컴팩션을 실행할 수 있어요.DISABLE— 테이블이 비활성화되어 모든 읽기/쓰기 접근을 방지해요.
간단한 공간 쿼터 설정 (Setting simple space quotas)
Sets a quota on the table 't1' with a limit of 1GB, disallowing Puts/Increments/Appends when the table exceeds 1GB
hbase> set_quota TYPE => SPACE, TABLE => 't1', LIMIT => '1G', POLICY => NO_INSERTS
Sets a quota on the namespace 'ns1' with a limit of 50TB, disallowing Puts/Increments/Appends/Deletes
hbase> set_quota TYPE => SPACE, NAMESPACE => 'ns1', LIMIT => '50T', POLICY => NO_WRITES
Sets a quota on the table 't3' with a limit of 2TB, disallowing any writes and compactions when the table exceeds 2TB.
hbase> set_quota TYPE => SPACE, TABLE => 't3', LIMIT => '2T', POLICY => NO_WRITES_COMPACTIONS
Sets a quota on the table 't2' with a limit of 50GB, disabling the table when it exceeds 50GB
hbase> set_quota TYPE => SPACE, TABLE => 't2', LIMIT => '50G', POLICY => DISABLE
네임스페이스에 쿼터를 설정하고 그 네임스페이스의 테이블 쿼터를 오버라이드하는 다음 시나리오를 고려하세요.
테이블 및 네임스페이스 공간 쿼터 (Table and Namespace space quotas)
hbase> create_namespace 'ns1' hbase> create 'ns1:t1' hbase> create 'ns1:t2' hbase> create 'ns1:t3' hbase> set_quota TYPE => SPACE, NAMESPACE => 'ns1', LIMIT => '100T', POLICY => NO_INSERTS hbase> set_quota TYPE => SPACE, TABLE => 'ns1:t2', LIMIT => '200G', POLICY => NO_WRITES hbase> set_quota TYPE => SPACE, TABLE => 'ns1:t3', LIMIT => '20T', POLICY => NO_WRITES
위 시나리오에서 네임스페이스 ns1의 테이블들은 서로 합쳐 파일시스템의 100TB를 초과해 공간을 소비할 수 없어요. 테이블 'ns1:t2'는 200GB 크기만 허용되며, 사용량이 이 한도를 초과하면 모든 쓰기가 금지돼요. 테이블 'ns1:t3'는 20TB까지 자랄 수 있고 사용량이 이 한도를 초과하면 모든 쓰기가 금지돼요. 'ns1:t1'에는 테이블 쿼터가 없으므로 이 테이블은 100TB까지 자랄 수 있지만, 'ns1:t2'와 'ns1:t3'의 사용량이 0바이트일 때만 그래요. 실질적으로 그 한도는 'ns1:t2'와 'ns1:t3'의 현재 사용량을 뺀 100TB예요.
자동 공간 쿼터 삭제 비활성화 (Disabling Automatic Space Quota Deletion)
기본적으로 공간 쿼터가 있는 테이블이나 네임스페이스가 삭제되면 쿼터 자체도 삭제돼요. 어떤 경우에는 공간 쿼터를 자동으로 삭제하지 않는 것이 바람직할 수 있어요. 그런 경우 사용자는 hbase-site.xml을 통해 시스템이 어떤 공간 쿼터도 자동으로 삭제하지 않도록 구성할 수 있어요.
기본값은 true예요.
공간 쿼터가 있는 HBase 스냅샷 (HBase Snapshots with Space Quotas)
HBase에서 의도하지 않은 파일시스템 사용의 한 가지 흔한 영역은 HBase 스냅샷을 통한 것이에요. 스냅샷이 HBase 테이블 관리 밖에 존재하므로, 수백 기가바이트나 테라바이트의 공간이 잊혀진 채 제거되지 않은 HBase 스냅샷에 사용되고 있다는 것을 관리자가 갑자기 깨닫는 것은 드문 일이 아니에요.
HBASE-17748은 원래 공간 쿼터 기능을 확장해 HBase 스냅샷도 포함하는 우산(umbrella) JIRA 이슈예요. 혼란스러운 주제이지만 구현은 관리자에게 합리적이고 간단한 방식으로 이 지원을 제시하려 해요. 이 기능은 관리자의 공간 쿼터 상호작용을 변경하지 않으며, 테이블/네임스페이스 사용량의 내부 계산만 변경해요. 테이블과 네임스페이스 사용량은 아래 정의된 규칙에 따라 스냅샷이 차지하는 크기를 자동으로 포함해요.
복습 겸 스냅샷의 수명 주기를 다뤄볼게요. 스냅샷은 파일시스템의 HFile 목록을 가리키는 메타데이터예요. 이것이 스냅샷 생성이 매우 저렴한 연산인 이유예요. 스냅샷을 수행하기 위해 실제 HBase 테이블 데이터가 복사되지 않아요. 스냅샷을 새 테이블로 clone하거나 테이블을 restore하는 것도 같은 이유로 저렴한 연산이에요. 새 테이블이 복사 없이 파일시스템에 이미 존재하는 파일을 참조하니까요. 스냅샷을 공간 쿼터에 포함하려면, 스냅샷이 파일을 참조할 때 어떤 테이블이 그 파일을 "소유"하는지 정의해야 해요("소유"는 그 파일의 파일시스템 사용을 포괄한다는 뜻이에요).
테이블에 대해 만들어진 스냅샷을 고려해 봐요. 스냅샷이 파일을 참조하고 테이블이 더 이상 그 파일을 참조하지 않으면, "기원" 테이블이 그 파일을 "소유"해요. 여러 스냅샷이 같은 파일을 참조하고 어떤 테이블도 그 파일을 참조하지 않으면, 이름이 가장 낮게 정렬되는(사전식) 스냅샷이 선택되고 그 스냅샷이 만들어진 테이블이 그 파일을 "소유"해요. 테이블과 하나 이상의 스냅샷이 그 HFile을 참조할 때 HFile은 "이중 계산"되지 않아요.
테이블이(clone_snapshot 또는 restore_snapshot을 통해) "rematerialize"되면 유사한 파일 소유권 문제가 발생해요. 이 경우 rematerialize된 테이블이 스냅샷도 참조하는 파일을 참조하지만, 테이블은 그 파일을 "소유"하지 않아요. 스냅샷이 만들어진 테이블이 여전히 그 파일을 "소유"해요. rematerialize된 테이블이 컴팩트되거나 스냅샷이 삭제되면, rematerialize된 테이블은 새 파일을 유일하게 참조하고 그 파일의 사용을 "소유"해요. 마찬가지로 테이블이 스냅샷과 restore_snapshot을 통해 복제될 때, 원래 테이블이 파일 참조를 멈추기 전까지(원래 테이블의 컴팩션, 새 테이블의 컴팩션, 또는 원래 테이블 삭제 중 하나로) 새 테이블은 어떤 쿼터 크기도 소비하지 않아요.
HBase 인스턴스의 각 스냅샷의 계산된 크기를 검사하는 새 HBase 셸 명령이 하나 추가됐어요.
hbase> list_snapshot_sizes SNAPSHOT SIZE t1.s1 1159108