Broker 구성

Broker 구성

Apache Pinot Broker의 구성 속성 레퍼런스 문서예요.

출처: 문서

본문

공유 MSE 사서함 keep-alive 속성(pinot.query.runner.channel.keep.alive.* 및 pinot.query.runner.mailbox.server.permit.keep.alive.*)은 Mailbox channel keep-alive를 참고하세요.

broker 속성은 구성 파일에 설정할 수 있어요. 파일은 시작 시 다음과 같이 제공할 수 있어요:

bin/pinot-admin.sh StartBroker -configFileName /path/to/broker.conf

구성 파일의 중복 키 (Duplicate Keys)

Apache Pinot 1.3.0부터 구성 파일의 중복 키는 시작 시 ConfigurationException을 발생시켜요. 이전에는 중복 키가 목록으로 조용히 병합됐어요. 이 오류가 발생하면 각 구성 속성이 구성 파일에 한 번만 나타나는지 확인하세요. 예외에는 정확한 파일 경로, 중복 키 이름, 중복이 발견된 줄 번호가 포함돼요.

예시 오류:

ConfigurationException: Duplicate key found in /path/to/broker.conf at line 10 and line 15: pinot.broker.timeoutMs

broker.conf는 다음 속성을 가질 수 있어요. 모든 속성은 이 클래스에 정의돼 있어요.

Broker 구성 속성 테이블

속성 기본값 설명
pinot.broker.delayShutdownTimeMs 10초 Broker 종료 지연 시간 (밀리초)
pinot.broker.enableTableLevelMetrics true 테이블 수준 메트릭 활성화 여부
pinot.broker.query.response.limit Integer.MAX_VALUE pinot.broker.enable.query.limit.override가 활성화된 경우, selection 쿼리가 이 값을 초과하면 limit을 재설정해요.
pinot.broker.query.log.length Integer.MAX_VALUE 쿼리 로그 길이
pinot.broker.query.log.maxRatePerSecond 10000.0 초당 로깅되는 최대 쿼리 수. 예외가 있거나 1초보다 오래 걸린 쿼리는 항상 로깅돼요.
pinot.broker.query.log.sqlRedaction none broker 쿼리 로그의 SQL 텍스트를 제어해요. none은 전체 SQL을 한 물리 로그 줄에 기록하고, Pinot은 역슬래시, 캐리지 리턴, 줄 바꿈을 \\, \r, \n으로 이스케이프해요. literal_values는 리터럴을 지문(fingerprint) 플레이스홀더로 대체하면서 쿼리 구조를 유지하고, full은 SQL 대신 REDACTED를 기록해요. 잘못된 값은 민감한 SQL 로깅을 피하기 위해 기본적으로 full로 처리돼요.
pinot.broker.enable.query.fingerprinting false true이면 broker가 single-stage와 multi-stage 엔진이 처리하는 쿼리에 대해 정규화된 지문과 queryHash를 계산해 관측 가능성을 위해 queryHash를 다운스트림 서버나 multi-stage 워커에 전파해요.
pinot.query.multistage.explain.include.segment.plan false true이면 multi-stage 엔진의 EXPLAIN PLAN FOR이 논리 계획 대신 기본적으로 세그먼트 계획을 포함해요. 쿼리별 explainAskingServers 쿼리 옵션이 이 설정을 덮어써요.
pinot.broker.timeoutMs 10초 Broker 쿼리 타임아웃 (밀리초)
pinot.broker.min.init.indexed.table.capacity 128 group-by 결과를 리듀스하는 동안 Pinot이 사용하는 broker 측 IndexedTable의 최소 초기 용량. 이 값을 늘리면 대규모 group-by 결과 집합의 재해싱을 줄일 수 있지만 작은 쿼리의 메모리 사용량은 늘어나요. 쿼리별로 SET minInitialIndexedTableCapacity = value로 덮어쓸 수 있어요.
pinot.broker.extraPassiveTimeoutMs 100 multi-stage 쿼리에서 timeoutMs 외에 스테이지 간 수동 대기(예: 업스트림 워커에서 사서함 데이터 대기)에 더하는 추가 시간(밀리초).
pinot.broker.startup.minResourcePercent 100 이 broker가 서빙해야 하는 총 테이블 수 대비 ONLINE인 리소스(테이블) 비율이 이 임계값 퍼센트를 넘으면 broker ServiceStatus가 STARTED로 간주되는 구성.
pinot.broker.startup.preconnect.enabled true Netty single-stage 전송에서 Helix 수렴 후 그리고 broker가 ready를 보고하기 전에 broker-서버 채널을 열어요. broker-서버 TLS가 활성화된 경우 TLS 핸드셰이크도 포함돼요. 비활성화하면 첫 쿼리에서 지연 연결로 복원돼요.
pinot.broker.startup.preconnect.timeoutMs 30000 시작 pre-connect 최대 예산(밀리초). 예산이 만료되면 broker가 ready를 보고하고 나머지 채널은 처음 사용될 때 지연 연결돼요.
pinot.broker.startup.warmup.enabled false HTTP readiness가 ready를 보고하기 전에 쿼리 서빙 경로를 워밍하기 위해 Helix 수렴 후 제한된 single-stage 프로브 쿼리를 실행해요.
pinot.broker.startup.warmup.budgetMs 30000 전체 시작 워밍업의 하드 제한(밀리초). 워밍업이 깊이 목표에 도달하지 못했어도 예산이 만료되면 readiness가 열려요.
pinot.broker.startup.warmup.minIterations 1000 예산 만료 전에 워밍업을 완료하는 데 필요한 성공적인 프로브 수.
pinot.broker.startup.warmup.concurrency 1 라운드당 동시에 실행할 시작 워밍업 프로브 수.
pinot.broker.enable.query.limit.override false 너무 많은 레코드를 가져오는 것에서 Pinot Broker와 Server를 보호하기 위해 Query LIMIT Override를 활성화하는 구성.
pinot.broker.query.ignore.missing.segments false true이면 broker가 ignoreMissingSegments 쿼리 옵션을 기본값으로 설정해 세그먼트 삭제나 이동 후 짧은 라우팅 지연으로 인한 SERVER_SEGMENT_MISSING 오류를 허용해요. single-stage 엔진에서는 쿼리를 단일 서버로 라우팅할 때만 적용되고, multi-stage 엔진에서는 쿼리가 이미 ignoreMissingSegments를 설정하지 않은 한 적용돼요.
pinot.broker.use.mse.to.fill.empty.response.schema false true이면 0행을 반환하는 single-stage 쿼리에 대해 useMSEToFillEmptyResponseSchema 쿼리 옵션을 기본값으로 설정해요. 매우 큰 IN 절에 의존하지 않는 워크로드에서만 활성화하세요.
pinot.broker.mse.enable.group.trim false multi-stage 쿼리에 대해 쿼리가 명시적으로 설정하지 않으면 집계 힌트 is_enable_group_trim을 기본값으로 설정해요.
pinot.broker.mse.streaming.group.by.flush.threshold unset multi-stage GROUP BY 쿼리에 대해 쿼리가 명시적으로 설정하지 않으면 streamingGroupByFlushThreshold 쿼리 옵션을 기본값으로 설정해요.
pinot.broker.query.log.logBeforeProcessing true 처리 전 수신(QUERY_RECEIVED) 레코드를 기록할지 여부.
pinot.broker.grpc.port -1 Broker gRPC API가 노출되는 포트.
pinot.broker.grpc.tls.enabled false Broker gRPC 보안 리스너 활성화 여부.
pinot.broker.grpc.tls.port -1 Broker gRPC TLS 리스너 포트.
pinot.broker.max.reduce.threads.per.query min(10, cores/2) 단일 쿼리에 대해 여러 서버의 결과를 리듀스(병합)하는 데 사용되는 최대 스레드 수.
pinot.broker.failure.detector.type NO_OP 비정상 서버 감지용 장애 감지기 유형. 옵션: NO_OP, CONNECTION, CUSTOM. 기본 NO_OP은 서버를 제외하지 않아요. CONNECTION은 쿼리 연결 실패 시 서버를 비정상으로 표시하고 지수 백오프로 재시도해요. CUSTOM은 pinot.broker.failure.detector.class를 로드해요.
pinot.broker.failure.detector.class 커스텀 FailureDetector 구현의 정규화된 클래스 이름. pinot.broker.failure.detector.type=CUSTOM일 때 필요해요.
pinot.broker.failure.detector.retry.initial.delay.ms 5000 비정상으로 표시된 서버를 재시도하기 전 초기 지연(밀리초). 이후 각 재시도는 이 지연에 pinot.broker.failure.detector.retry.delay.factor를 곱해요.
pinot.broker.failure.detector.retry.delay.factor 2.0 각 실패한 상태 재시도 후 재시도 지연에 적용되는 지수 백오프 계수.
pinot.broker.failure.detector.max.retries 10 비정상 서버에 대한 최대 상태 재시도 수. 이 횟수를 넘으면 broker가 서버를 다시 정상으로 취급해 라우팅이 서버를 잃지 않게 해요.
pinot.broker.use.fixed.replica false true이면 더 나은 캐시 지역성을 위해 고정 복제본 그룹으로 쿼리를 라우팅해요.
pinot.broker.multistage.use.broker.pruning true physical optimizer 경로의 multi-stage 쿼리에 대해 useBrokerPruning 쿼리 옵션을 기본값으로 설정해 dispatch 전에 적격 서버와 세그먼트를 프루닝해요.
pinot.broker.multistage.logical.planner.use.broker.pruning true logical planner 경로의 multi-stage 쿼리에 대해 적격 비파티션 리프, 파티션 리프, 논리 테이블, 동일 위치 조인에 useBrokerPruning을 기본값으로 설정해요.
pinot.query.multistage.dispatch.channel.keep.alive.time.ms 300000 MSE에서 중간 스테이지 워커로의 broker dispatch 채널에 대한 gRPC keep-alive 간격(밀리초).
pinot.query.multistage.dispatch.channel.keep.alive.timeout.ms 30000 MSE에서 broker dispatch 채널에 대한 gRPC keep-alive ACK 타임아웃(밀리초).
pinot.query.multistage.dispatch.channel.keep.alive.without.calls false MSE에서 idle(활성 호출 없음) 동안에도 broker dispatch 채널이 keep-alive ping을 보낼지 여부.
pinot.broker.adaptive.server.selector.enable.stats.metric.export false adaptive-routing 게이지를 broker 메트릭으로 내보내기 위한 초기값.
pinot.broker.adaptive.server.selector.stats.metric.export.interval.ms 10000 adaptive-routing 게이지 주기 내보내기 초기 간격(밀리초).
pinot.broker.multistage.use.physical.optimizer false multi-stage 쿼리 엔진의 physical optimizer 활성화 여부.
pinot.broker.multistage.unnest.column.pruning false logical planner 경로의 multi-stage UNNEST 쿼리에 대해 unnestColumnPruning 쿼리 옵션을 기본값으로 설정해 사용되지 않는 passthrough 컬럼을 UNNEST 출력에서 프루닝해요.
pinot.broker.multistage.infer.partition.hint false multi-stage 쿼리 엔진에서 데이터 셔플링 최적화를 위한 파티션 힌트 추론.
pinot.broker.multistage.default.hash.function absHashCode multi-stage 엔진에서 데이터 파티셔닝용 기본 해시 함수.
pinot.broker.mse.planner.disabled.rules Built-in disabled-rule set broker가 기본적으로 비활성화된 것으로 취급해야 하는 MSE 플래너 규칙 이름의 쉼표 구분 목록.
pinot.broker.mse.max.server.query.threads -1 multi-stage 쿼리용 broker-로컬 동시성 스로틀(추정 서버 쿼리 스레드 단위).
pinot.broker.mse.max.server.query.threads.exceed.strategy WAIT multi-stage 쿼리가 broker 측 동시성 스로틀을 초과할 때의 동작. 지원 값: WAIT(용량이 생길 때까지 차단) 및 LOG(쿼리 허용하되 경고 기록).
pinot.broker.mse.stream.stats false multi-stage 쿼리에 대해 스트리밍 SubmitWithStream stats 경로를 기본값으로 사용해 long-lived gRPC 스트림으로 스테이지 통계를 푸시해요.
pinot.broker.mse.stream.stats.drain.ms 50 쿼리 결과 사서함이 끝난 후 trailing 스테이지 통계를 드레이닝하는 최선 노력 대기 기간(밀리초).
pinot.broker.request.handler.type netty broker-서버 통신용 요청 핸들러 유형. 옵션: netty, grpc, multistage.
channelKeepAliveTimeSeconds -1 (disabled) broker-서버 gRPC 쿼리 클라이언트 keepalive 간격(초)을 위한 최상위 broker.conf 키. pinot.broker.request.handler.type=grpc일 때만 적용돼요.
channelKeepAliveTimeoutSeconds 20 broker-서버 gRPC 쿼리 클라이언트의 keepalive ACK 타임아웃(초).
channelKeepAliveWithoutCalls true idle 상태에서도 broker-서버 gRPC 쿼리 클라이언트가 keepalive ping을 보낼지 제어하는 최상위 키.
channelShutdownTimeoutSeconds 10 종료 중 broker-서버 gRPC 쿼리 클라이언트 채널이 종료될 때까지 broker가 기다리는 시간(초).

라우팅 쿼리 수신 로그 (Routing query-received logs)

org.apache.pinot.broker.querylog.QueryLogger 로거는 전처리 SQL query for request ... 레코드와 통계가 포함된 쿼리 완료 레코드를 모두 방출해요. 전처리 레코드만 SLF4J 마커 QUERY_RECEIVED를 전달하므로 메시지 텍스트를 매칭하지 않고도 독립적으로 필터링하거나 라우팅할 수 있어요.

예를 들어 로그를 보내는 appender에 다음 Log4j2 필터를 추가해 query-received 레코드를 해당 대상에서 제외할 수 있어요:

<MarkerFilter marker="QUERY_RECEIVED" onMatch="DENY" onMismatch="NEUTRAL"/>

로컬 포렌식용으로 수신 레코드가 필요하면 필터링되지 않은 다른 대상을 유지하세요. 완료되지 않는 쿼리에는 완료 레코드가 없을 수 있어요. 마커를 추가해도 로깅이 비활성화되거나 메시지 텍스트가 바뀌지 않아요. pinot.broker.query.log.logBeforeProcessing은 기본적으로 true로 유지되며, false로 설정하면 수신 레코드를 아예 비활성화해요.

Broker 시작 pre-connect

Broker 시작 pre-connect는 첫 single-stage 쿼리에서 각 서버로 보내는 TCP 연결과(구성 시) TLS 핸드셰이크를 제거해요. Helix 수렴 후 broker는 라우팅 테이블의 모든 (server, table type) 쌍에 대해 하나의 Netty 채널을 열어요. broker는 pre-connect가 끝나거나 pinot.broker.startup.preconnect.timeoutMs에 도달할 때까지 STARTING 상태로 남아요.

Pre-connect는 기본적으로 활성화되며 best effort예요. 느리거나 사용 불가한 서버는 구성된 예산을 초과해도 시작을 막지 않으며, 준비되지 않은 채널은 기존 지연 연결 경로로 대체돼요. OFFLINE과 REALTIME 경로가 별도 채널을 사용하므로 두 유형을 모두 호스팅하는 서버는 두 연결을 받을 수 있어요.

구성된 타임아웃이 유일한 조기 해제 경계예요. Pre-connect는 시도된 모든 채널이 연결되었거나 실패하는 즉시 반환하고, 그렇지 않으면 마감까지 기다려요. 이 기능은 broker가 Netty single-stage 전송을 사용할 때만 적용돼요. broker-서버 gRPC 핸들러, multi-stage 엔진, 시계열 경로에는 채널을 워밍하지 않아요.

이전 동작(첫 쿼리가 각 채널을 설정)을 복원하려면:

pinot.broker.startup.preconnect.enabled=false

라우팅된 서버가 많거나 TLS 핸드셰이크가 느린 배포에서는 오케스트레이션 시스템이 허용하는 최대 시작 지연보다 낮게 유지하면서 예산을 늘리세요:

pinot.broker.startup.preconnect.enabled=true
pinot.broker.startup.preconnect.timeoutMs=60000

STARTUP_PRECONNECT_DURATION_MS로 시작 워밍업 시간을, NETTY_CONNECTION_CONNECT_LATENCY_MS로 개별 채널 연결 시간 분포를 모니터링하세요.

Broker 쿼리 서빙 경로 워밍업 (Broker query serve-path warmup)

Broker 쿼리 서빙 경로 워밍업은 HTTP readiness가 부여되기 전에 single-stage 컴파일, 라우트, scatter-gather, 역직렬화, 리듀스, 응답 직렬화 경로를 실행해 재시작 후 첫 트래픽 폭증 동안의 지연을 줄여요. 기본적으로 비활성화되어 있으며 시작 pre-connect를 보완해요.

활성화되면 broker는 Helix 수렴 후 먼저 로컬 컴파일과 응답 직렬화 작업을 수행한 다음 고정 SELECT * FROM "<table>" LIMIT 1 프로브를 발행하면서 STARTING 상태로 유지돼요. Pinot은 해당 broker에 보이는 모든 서버를 커버하는 결정적 라우팅 가능 테이블 집합을 선택해요. 합성 프로브는 액세스 제어, 쿼리 할당량, 고객 쿼리 로그, 일반 쿼리 메트릭을 우회해요.

워밍업은 pinot.broker.startup.warmup.minIterations 프로브가 성공하거나 pinot.broker.startup.warmup.budgetMs가 만료되면 완료돼요. 오류, 중단, 예산 소진은 readiness 게이트를 해제하므로 워밍업이 롤링 재시작을 무한정 차단할 수 없어요.

pinot.broker.startup.warmup.enabled=true
pinot.broker.startup.warmup.budgetMs=30000
pinot.broker.startup.warmup.minIterations=1000
pinot.broker.startup.warmup.concurrency=1

이 워밍업은 Netty single-stage 쿼리 경로에만 적용돼요. 게이트는 HTTP readiness에 영향을 주지만 워밍하는 동안 broker를 Helix 디스커버리에서 제거하지는 않아요.

다음 broker 메트릭을 모니터링하세요:

  • STARTUP_WARMUP_COMPLETE: 워밍업 활성 중 0, readiness 진행 가능 시 1, 비활성화 시 항상 1.
  • STARTUP_WARMUP_DURATION_MS: Helix 수렴부터 워밍업 게이트 해제까지의 전체 시간.
  • STARTUP_WARMUP_UNCOVERED_SERVERS: 선택된 프로브 테이블이 커버하지 못한 라우팅 서버 수, 보통 0.

장애 감지기 (Failure detector)

기본값(NO_OP)은 broker가 비정상 서버를 추적하지 않아요. pinot.broker.failure.detector.type=CONNECTION으로 설정하면 쿼리가 연결 실패를 만날 때 서버를 비정상으로 표시하고 라우팅에서 제외한 뒤 나중에 재시도해요.

재시도는 지수 백오프(retry.initial.delay.ms, retry.delay.factor)를 사용해요. max.retries 후 broker는 리스너가 서버를 잃지 않도록 다시 정상으로 표시해요.

CUSTOM은 pinot.broker.failure.detector.class에 있는 클래스를 로드해요. 값은 NO_OP, CONNECTION, CUSTOM이에요.

Broker gRPC 전송 (Broker gRPC transport)

Pinot broker는 두 가지 다른 gRPC 쿼리 경로에 참여할 수 있어요:

  • 클라이언트 → broker: broker는 pinot.broker.grpc.port 또는 pinot.broker.grpc.tls.port에서 Broker gRPC API를 노출해요.
  • broker → 서버: broker는 pinot.broker.request.handler.type=grpc일 때만 Pinot 서버와 gRPC로 통신해요.

보안 broker gRPC 리스너의 경우 Pinot은 현재 pinot.broker.tls.* 아래에 구성된 TLS 자료를 재사용해요. 즉 pinot.broker.grpc.tls.enabled와 pinot.broker.grpc.tls.port가 보안 리스너를 선택하고, 키스토어와 트러스트스토어는 일반 broker TLS 접두사에서 가져와요.

예시:

pinot.broker.grpc.port=8010
pinot.broker.grpc.tls.enabled=true
pinot.broker.grpc.tls.port=8020

pinot.broker.tls.keystore.path=/path/to/broker-keystore.p12
pinot.broker.tls.keystore.password=changeit
pinot.broker.tls.keystore.type=PKCS12
pinot.broker.tls.truststore.path=/path/to/broker-truststore.p12
pinot.broker.tls.truststore.password=changeit
pinot.broker.tls.truststore.type=PKCS12

pinot.broker.request.handler.type=grpc를 사용하면 broker의 서버로 향하는 아웃바운드 gRPC 채널을 위의 keepalive 및 shutdown 설정으로 튜닝할 수 있어요. channelKeepAliveTimeSeconds가 양수로 설정되지 않는 한 keepalive는 비활성화된 상태로 유지돼요.

예시:

pinot.broker.request.handler.type=grpc

channelKeepAliveTimeSeconds=60
channelKeepAliveTimeoutSeconds=20
channelKeepAliveWithoutCalls=true
channelShutdownTimeoutSeconds=10

더 알아보기 (Learn more)