테넌트
테넌트 (Tenant)
Apache Pinot의 테넌트 구성 요소를 살펴보는 페이지예요. 테넌트는 Pinot 클러스터 내에서 효율적인 데이터 격리와 리소스 관리를 가능하게 해줘요.
출처: Tenant
본문
모든 테이블은 [테넌트]와 연결돼요. 테넌트는 클러스터가 테이블에 대한 쿼리를 처리하는 위치를 제한하는 논리 네임스페이스예요. Pinot 테넌트는 논리 테넌트 네임스페이스의 텍스트 태그 형태를 취해요. 물리적 클러스터 하드웨어 리소스(즉, 브로커와 서버)도 공통 테넌트 네임스페이스의 테넌트 태그와 연결돼요. 특정 테넌트 태그의 테이블은 같은 테넌트 태그에 속하는 하드웨어 리소스에서만 스토리지와 쿼리 처리를 위해 스케줄링돼요. 이를 통해 Pinot 클러스터 운영자는 특정 워크로드를 특정 하드웨어 리소스에 할당해서, 서로 다른 워크로드의 데이터가 같은 물리 하드웨어에 저장되거나 처리되는 것을 방지할 수 있어요.
기본적으로 모든 테이블, 브로커, 서버는 DefaultTenant라는 테넌트에 속하지만, Pinot 클러스터에서 여러 테넌트를 구성할 수 있어요. 클러스터에 여러 테넌트가 계획되어 있다면 cluster.tenant.isolation.enable=false를 설정해서 서버와 브로커가 클러스터에 추가될 때 자동으로 DefaultTenant로 태그되지 않도록 고려하세요.
멀티 테넌시를 지원하기 위해 Pinot는 테넌트를 일급 기능(first class)으로 지원해요. 모든 테이블은 서버 테넌트와 브로커 테넌트와 연결되며, 이는 테이블이 서버와 브로커로 사용하는 노드를 제어해요. 멀티 테넌시를 통해 Pinot는 특정 사용 사례에 속하는 모든 테이블을 단일 테넌트 이름 아래 그룹화할 수 있어요.
여러 사용 사례가 Pinot를 사용하고 테넌트 간에 쿼터나 어떤 종류의 격리를 제공할 필요가 있을 때 테넌트의 개념은 매우 중요해요. 예를 들어 같은 Pinot 클러스터에 Table A와 Table B라는 두 테이블이 있다고 생각해 보세요.

Table A는 서버 테넌트 Tenant A로, Table B는 서버 테넌트 Tenant B로 구성할 수 있어요. 일부 서버 노드에 Tenant A 태그를, 일부에 Tenant B 태그를 붙일 수 있어요. 이렇게 하면 Table A의 세그먼트는 Tenant A로 태그된 서버에만, Table B의 세그먼트는 Tenant B로 태그된 서버에만 존재하도록 보장돼요. 테이블에 브로커 테넌트를 구성하면 브로커 수준에서도 동일한 격리를 얻을 수 있어요.

테이블이나 사용 사례마다 별도의 클러스터를 만들 필요가 없어요!
테넌트 구성 (Tenant configuration)
테넌트는 테이블 설정의 tenants 섹션에 정의돼요.
이 섹션에는 broker와 server라는 두 가지 주요 필드가 있으며, 이 테이블의 브로커와 서버 구성 요소에 사용되는 테넌트를 결정해요.
"tenants": {
"broker": "brokerTenantName",
"server": "serverTenantName"
}
위 예제에서:
- 테이블은 Helix에서
brokerTenantName_BROKER로 태그된 브로커가 제공해요. - 오프라인 테이블이라면 테이블의 오프라인 세그먼트는 Helix에서
serverTenantName_OFFLINE으로 태그된 Pinot 서버에 호스팅돼요. - 실시간 테이블이라면 실시간 세그먼트(consuming 및 completed 모두)는 Helix에서
serverTenantName_REALTIME으로 태그된 Pinot 서버에 호스팅돼요.
테넌트 생성 (Create a tenant)
POST /tenants는 현재 태그되지 않은 브로커 또는 서버 인스턴스에 태그를 붙여 테넌트를 만들어요. JSON 본문은 Tenant 설정에 매핑돼요:
| 필드 | Broker | Server | 참고 |
|---|---|---|---|
tenantRole |
필수 (BROKER) |
필수 (SERVER) |
역할이 태그되는 인스턴스 풀을 선택해요. |
tenantName |
필수 | 필수 | 논리 테넌트 이름 (Helix 태그는 _BROKER, _OFFLINE, _REALTIME 접미사를 사용해요). |
numberOfInstances |
필수 | 필수 | 이 테넌트에 할당할 태그 없는 인스턴스 총 수. 생략하면 기본 0이 되고, 이 경우 서버 생성이 Cannot request more offline instances ... than total instances: 0 같은 오류로 실패해요. |
offlineInstances |
해당 없음 | 서버 테넌트에 필수 | 할당된 서버 중 몇 개가 {tenant}_OFFLINE 태그를 받는지. |
realtimeInstances |
해당 없음 | 서버 테넌트에 필수 | 할당된 서버 중 몇 개가 {tenant}_REALTIME 태그를 받는지. |
서버 테넌트의 경우 Pinot는 다음을 검증해요:
numberOfInstances >= offlineInstancesnumberOfInstances >= realtimeInstances
이 검사는 offlineInstances + realtimeInstances가 아니라 태그 유형별로 이루어져요. offlineInstances + realtimeInstances > numberOfInstances이지만 각 개수가 여전히 numberOfInstances에 들어맞으면 Pinot는 태그를 함께 배치(co-locate)해요. 같은 물리 서버가 {tenant}_OFFLINE과 {tenant}_REALTIME 둘 다 받을 수 있어요. 생성에는 여전히 최소 numberOfInstances개의 태그 없는 온라인 서버(브로커 테넌트는 브로커)가 필요해요. 이미 태그된 인스턴스는 POST /tenants가 재할당하지 않아요.
브로커 테넌트 (Broker tenant)
다음은 샘플 브로커 테넌트 설정이에요. 태그되지 않은 브로커 노드 세 개를 sampleBrokerTenant_BROKER로 태그해 브로커 테넌트 sampleBrokerTenant를 만들어요.
{
"tenantRole": "BROKER",
"tenantName": "sampleBrokerTenant",
"numberOfInstances": 3
}
태그 없는 브로커 노드 수가 numberOfInstances보다 적으면 생성이 실패해요.
pinot-admin.sh:
Getting Pinot 지침에 따라 Pinot를 로컬로 받은 다음:
bin/pinot-admin.sh AddTenant \
-name sampleBrokerTenant \
-role BROKER \
-instanceCount 3 \
-exec
curl:
curl -i -X POST -H 'Content-Type: application/json' \
-d @sample-broker-tenant.json \
http://localhost:9000/tenants
Rest API에서 테넌트 목록을 확인해 테넌트가 생성됐는지 확인하세요.
서버 테넌트 (Server tenant)
다음은 샘플 서버 테넌트 설정이에요. numberOfInstances: 2로 태그 없는 서버 하나를 sampleServerTenant_OFFLINE으로, 다른 하나를 sampleServerTenant_REALTIME으로 태그해요.
{
"tenantRole": "SERVER",
"tenantName": "sampleServerTenant",
"numberOfInstances": 2,
"offlineInstances": 1,
"realtimeInstances": 1
}
한 서버에 offline과 realtime을 함께 배치 (태그 없는 서버 하나가 두 태그를 모두 받음):
{
"tenantRole": "SERVER",
"tenantName": "sampleServerTenant",
"numberOfInstances": 1,
"offlineInstances": 1,
"realtimeInstances": 1
}
태그 없는 서버 노드가 numberOfInstances보다 적거나, offlineInstances 또는 realtimeInstances가 numberOfInstances보다 크면 생성이 실패해요.
pinot-admin.sh:
Getting Pinot 지침에 따라 Pinot를 로컬로 받은 다음:
bin/pinot-admin.sh AddTenant \
-name sampleServerTenant \
-role SERVER \
-instanceCount 2 \
-offlineInstanceCount 1 \
-realTimeInstanceCount 1 \
-exec
-instanceCount는 모든 AddTenant 호출에 필수예요. SERVER 역할의 경우 -offlineInstanceCount와 -realTimeInstanceCount도 필수예요 (-realTimeInstanceCount의 대문자 T에 주의).
curl:
curl -i -X POST -H 'Content-Type: application/json' \
-d @sample-server-tenant.json \
http://localhost:9000/tenants
Rest API에서 테넌트 목록을 확인해 테넌트가 생성됐는지 확인하세요.
태그 없는 용량이 없는 인스턴스 태깅 (Tagging instances without untagged capacity)
POST /tenants는 태그 없는 브로커/서버 풀만 소비해요. 서버가 이미 태그되어 있고(예: DefaultTenant_OFFLINE) 해당 인스턴스에서 테넌트 태그를 이동하거나 추가하려면 POST /tenants가 다시 태그해주기를 기대하지 말고 인스턴스 태그를 직접 업데이트하세요:
curl -i -X PUT \
"http://localhost:9000/instances/Server_host1_8098/updateTags?tags=sampleServerTenant_OFFLINE,sampleServerTenant_REALTIME"
Instances API를 통해 인스턴스를 추가하거나 업데이트할 때도 태그를 설정할 수 있어요. 격리 모델이 허용한다면 서버는 둘 이상의 태그(예: _OFFLINE과 _REALTIME 둘 다, 또는 둘 이상의 테넌트 태그)를 가질 수 있어요.
생성 후 기존 테넌트를 키우거나 줄이려면 같은 Tenant 페이로드 형태(두 역할 모두 numberOfInstances, 서버는 offline/realtime 개수 포함)로 PUT /tenants를 사용하세요.