0.11.0
0.11.0
Apache Pinot 0.11.0 릴리스 노트 문서예요. 이 릴리스는 분산 조인을 가능하게 하는 Multi-Stage 쿼리 엔진, 더 많은 SQL 문법(DML 지원), 쿼리 함수와 인덱스(Text 인덱스, Timestamp 인덱스) 등 쿼리 능력을 확장하는 많은 새 기능을 도입했어요. 또 Spark3, Flink 같은 다른 시스템과의 통합도 늘었어요.
출처: 문서
본문
요약 (Summary)
Apache Pinot 0.11.0은 쿼리 능력을 확장하는 많은 새 기능을 도입했어요. 예를 들어 Multi-Stage 쿼리 엔진은 Pinot이 분산 조인을 하게 해주고, 더 많은 SQL 문법(DML 지원), 쿼리 함수와 인덱스(Text 인덱스, Timestamp 인덱스)가 새로운 사용 사례를 지원해요. 그리고 언제나처럼 다른 시스템(예: Spark3, Flink)과의 더 많은 통합이 있어요.
참고: Apache Helix의 메이저 업그레이드(1.0.4)가 있어요. 반드시 다음 순서로 시스템을 업그레이드하세요:
Helix Controller → Pinot Controller → Pinot Broker → Pinot server
Multi-Stage 쿼리 엔진
참고: multi-stage 엔진은 이 릴리스(0.11.0)에서 실험적으로 도입됐고 Pinot 1.0.0에서 프로덕션 준비가 됐어요. 최신 문서는 SSE vs MSE와 MSE 트러블슈팅을 참고하세요.
multi-stage 쿼리 엔진(MSE 또는 v2라고도 함)은 JOIN, OVER window, MATCH_RECOGNIZE 같은 더 복잡한 SQL 의미를 지원하고, 궁극적으로 Pinot이 더 완전한 ANSI SQL 의미에 가깝게 지원하도록 설계됐어요.
더 읽기: SSE vs MSE

Apache Pinot에서 스트림 소비 일시 중지 (Pause Stream Consumption on Apache Pinot)
Pinot 연산자는 쿼리가 실행되는 동안 이벤트의 실시간 소비를 일시 중지하고, 다시 준비되면 소비를 재개할 수 있어요.

더 읽기: https://medium.com/apache-pinot-developer-blog/pause-stream-consumption-on-apache-pinot-772a971ef403
Gap-filling 함수 (Gap-filling function)
gapfilling 함수는 사용자가 데이터를 보간하고 시계열 데이터에 대해 강력한 집계와 데이터 처리를 수행할 수 있게 해줘요. 더 읽기: https://www.startree.ai/blog/gapfill-function-for-time-series-datasets-in-pinot
Spark 3.x 지원 추가 (#8560)
Spark 3.x에서 세그먼트 생성을 위한 오랫동안 기다려온 기능이에요.
Flink Pinot 커넥터 추가 (#8233)
Spark Pinot 커넥터와 유사하게, Flink 사용자가 Flink 애플리케이션에서 Pinot으로 데이터를 덤프할 수 있게 해줘요.
실행 중인 쿼리 표시 및 id로 쿼리 취소 (#9171)
이 기능은 pinot 쿼리에 대한 더 세밀한 제어를 가능하게 해요.
Timestamp 인덱스 (#8343)
사용자가 더 낮은 세분성의 timestamp 컬럼에서 더 나은 쿼리 성능을 얻을 수 있게 해줘요. 참고: docs
네이티브 Text 인덱스 (Native Text Indices) (#8384)
텍스트를 실시간으로 검색하고 싶나요? Pinot의 새 텍스트 인덱싱 엔진은 다음 기능을 지원해요:
- 새 연산자: LIKE
select * FROM foo where text_col LIKE 'a%'
- 새 연산자: CONTAINS
select * from foo where text_col CONTAINS 'bar'
- Pinot의 시계열 사용 사례에 초점을 맞추고 기존 Pinot 인덱스와 구조(inverted index, bitmap storage)를 활용해 처음부터 구축된 네이티브 텍스트 인덱스.
- 실시간 텍스트 인덱스
더 읽기: https://medium.com/@atri.jiit/text-search-time-series-style-681af37ba42e
DML 정의 및 SQL InsertFile 파싱 추가 (#8557)
이제 INSERT INTO [database.]table FROM FILE dataDirURI OPTION ( k=v ) [, OPTION (k=v)]*를 사용해 Minion으로 파일에서 Pinot으로 데이터를 로드할 수 있어요. 참고: docs
중복 제거 (Deduplication) (#8708)
이 기능은 최상위 테이블 구성으로 실시간 테이블의 중복 제거 활성화를 지원해요. 높은 수준에서는 (테이블 스키마에 정의된) primaryKey 해시를 인메모리 데이터 구조에 저장하고, 들어오는 각 행을 그것과 대조해 검증해요. 중복 행은 버려집니다.
이 기능을 사용할 때 기대 사항은 스트림이 primary key로 파티셔닝되고, strictReplicaGroup 라우팅이 활성화되며, 구성된 스트림 consumer 타입이 low level이어야 한다는 것이에요. 이러한 요구 사항은 테이블 구성 API의 입력 검증을 통해 강제됩니다.
함수 지원 및 변경 (Functions support and changes):
- arrayConcatLong, arrayConcatFloat, arrayConcatDouble 함수 지원 추가 (#9131)
- regexpReplace 스칼라 함수 지원 추가 (#9123)
- Base64 인코딩/디코딩 스칼라 함수 지원 추가 (#9114)
- 불필요한 ^._ 및 ._$를 포함하지 않도록 like에서 regexp 변환 최적화 (#8893)
- 여러 MV 컬럼의 DISTINCT 지원 (#8873)
- 단일 MV 컬럼의 DISTINCT 지원 (#8857)
- histogram 집계 함수 추가 (#8724)
- 형식을 한 번만 파싱하도록 dateTimeConvert 스칼라 함수 최적화 (#8939)
- 스칼라 함수의 켤레 지원, 더 많은 스칼라 함수 추가 (#8582)
- FIRSTWITHTIME 집계 함수 지원 추가 #7647 (#8181)
- PercentileSmartTDigestAggregationFunction 추가 (#8565)
- DistinctCountSmartHLLAggregationFunction 매개변수 단순화 (#8566)
- 컴파일 시간에 계산할 수 있도록 cast 스칼라 함수 추가 (#8535)
- Avg/Count/Sum용 확장 가능한 Gapfill 구현 (#8647)
- Pinot에 흔히 쓰는 math, string, date 스칼라 함수 추가 (#8304)
- Datetime 변환 함수 (#8397)
- url 인코딩 및 디코딩 스칼라 함수 (#8378)
- 변환 함수에서 IS NULL과 NOT IS NULL 지원 추가 (#8264)
- H3 인덱스를 사용한 st_contains 지원 (#8498)
이 릴리스에서 도입된 전체 기능 목록
- 브로커의 기능을 기반으로 한 controller의 쿼리 취소 API 추가 (#9276)
- 수집 작업에서 입력 파일을 재귀적으로 검색하는 옵션 추가. 이전 버전과 호환되도록 기본값은 true로 설정 (#9265)
- 각 컴포넌트의 로컬 로그 파일을 다운로드하는 엔드포인트 추가 (#9259)
- 진행 중인 controller 세그먼트 다운로드·업로드 요청을 추적하는 메트릭 추가 (#9258)
- 신선도(freshness) 기반 consumption 상태 체커 추가 (#9244)
- consuming 세그먼트 강제 커밋 (#9197)
- period와 timestamp용 kafka offset 지원 추가 (#9193)
- upsert 메타데이터 매니저를 플러그 가능하게 변경 (#9186)
- 로거 유틸 추가 및 런타임에 로거 레벨 변경 허용 (#9180)
- 모든 SV 컬럼 데이터 타입의 equality, inequality, membership 연산자에서 null 처리 개선 (#9173)
- 실행 중인 쿼리 표시 및 id로 쿼리 취소 지원 (#9171)
- upsert 메타데이터 처리 강화 (#9095)
- SV 데이터 타입의 집계 함수에서 null 처리 개선 (#9086)
- Kinesis 플러그인에서 IAM 역할 기반 자격 증명 지원 추가 (#9071)
- Task generator 디버그 api (#9058)
- Segment Lineage List API 추가 #9005 (#9006)
- [colocated-join] Table Config에 instancePartitionsMap 지원 추가 (#8989)
- 실시간 테이블의 소비 일시 중지/재개 지원 (#8986)
- #8970 Pinot UI의 Minion 탭 (#8978)
- Protocol Buffer 스트림 디코더 추가 (#8972)
- minion 태스크 메타데이터 ZNode 경로 업데이트 (#8959)
- /tasks/{taskType}/{tableNameWithType}/debug API 추가 (#8949)
- 총 쿼리 처리 시간용 새 브로커 메트릭 정의 (#8941)
- SELECT, ORDER BY, DISTINCT, GROUP BY의 null 처리 개선 (#8927)
- REGEX OPTION 파서 수정 (#8905)
- PulsarMessageBatch에서 key value byte stitching 활성화 (#8897)
- 패키지에 hadoop jar 추가를 건너뛰는 속성 추가 (#8888)
- 여러 MV 컬럼의 DISTINCT 지원 (#8873)
- Mutable FST 인덱스 구현 (#8861)
- 단일 MV 컬럼의 DISTINCT 지원 (#8857)
- 세그먼트 리로드 태스크 상태용 controller API 추가 (#8828)
- Spark 커넥터, TIMESTAMP와 BOOLEAN 필드 지원 (#8825)
- 구성에 기반해 METADATA push에서 moveToFinalLocation 허용 (#8823) (#8815)
- 비트맵 인덱스당 최대 4GB 허용 (#8796)
- 디버그 옵션 폐기 및 항상 쿼리 옵션 사용 (#8768)
- 디스크 사용량을 제어하기 위한 rate limiter가 있는 스트리밍 세그먼트 다운로드 & untar (#8753)
- Explain Plan 정확도 개선 (#8738)
- https를 기본 스킴으로 설정 허용 (#8729)
- histogram 집계 함수 추가 (#8724)
- PinotConfiguration 스위치로 점이 있는 테이블 이름 허용 (#8713)
- 기본적으로 Groovy 함수 비활성화 (#8711)
- 중복 제거 (#8708)
- 플러그 가능한 클라이언트 auth 제공자 추가 (#8670)
- pinot 파일시스템 명령 추가 (#8659)
- 브로커가 비싼 함수를 근사 대응 함수로 자동 재작성하도록 허용 (#8655)
- window 필터를 부정해 시간 창 밖의 데이터를 가져오도록 허용 (#8640)
- BigDecimal raw 값 forward index 지원; 많은 변환과 연산자에서 BigDecimal 지원 (#8622)
- 수집 집계 기능 (#8611)
- 실시간 테이블에 세그먼트 업로드 활성화 (#8584)
- kafka 0.9 shaded jar를 pinot-distribution에 패키징 (#8569)
- DistinctCountSmartHLLAggregationFunction 매개변수 단순화 (#8566)
- PercentileSmartTDigestAggregationFunction 추가 (#8565)
- Spark 3.x 지원 추가 (#8560)
- DML 정의 및 SQL InsertFile 파싱 추가 (#8557)
- minion 태스크 메타데이터를 가져오고 삭제하는 엔드포인트 (#8551)
- 더 많은 레플리카 그룹을 사용하는 쿼리 옵션 추가 (#8550)
- @ScalarFunction으로 애노테이션된 공개 메서드만 발견 (#8544)
- 스키마, 타입 변환, SQL 문, 최소 변환 집합에서 단일값 BigDecimal 지원 (#8503)
- 연결 기반 FailureDetector 추가 (#8491)
- minion 태스크에 대한 더 세밀한 제어 엔드포인트 추가 (#8486)
- adhoc minion 태스크 생성 엔드포인트 추가 (#8465)
- 인스턴스/세그먼트 수준의 표현식 힌트에 기반해 PinotQuery 재작성 (#8451)
- 높은 카디널리티 컬럼의 dict 생성 비활성화 허용 (#8398)
- 세그먼트 push 시 세그먼트 크기 메트릭 추가 (#8387)
- 네이티브 Text 연산자 구현 (#8384)
- consuming 세그먼트의 기본 메모리 할당을 on-heap에서 off-heap으로 변경 (#8380)
- 압축된 tar.gz와 레플리카 없는 테이블 크기를 위한 새 Pinot 스토리지 메트릭 (#8358)
- upsert heap 메모리 추정용 실험 API 추가 (#8355)
- Timestamp 타입 인덱스 (#8343)
- Pinot에서 Helix를 1.0.4로 업그레이드 (#8325)
- 쿼리 구성을 통해 쿼리의 표현식 오버라이드 허용 (#8319)
- 항상 null 시간 값 처리 (#8310)
- 수집 시 필드 이름 변경을 위한 prefixesToRename 구성 추가 (#8273)
- 오프라인 테이블의 다중 컬럼 파티셔닝 추가 (#8255)
- 브로커 변경 시 브로커 리소스 자동 업데이트 (#8249)
취약점 수정 (Vulnerability fixs)
Pinot은 모든 수준 높은 취약점 문제를 해결했어요:
- trivy로 취약점을 확인하는 새 워크플로 추가 (#9044)
- 기본적으로 Groovy 함수 비활성화 (#8711)
- 보안 취약점 때문에 netty 업그레이드 (#8328)
- 현재 버전에 보안 취약점이 있어 protobuf 업그레이드 (#8287)
- cve 때문에 hadoop 2.10.1로 업그레이드 (#8478)
- Helix를 1.0.4로 업그레이드 (#8325)
- thrift를 0.15.0으로 업그레이드 (#8427)
- 보안 문제 때문에 jetty 업그레이드 (#8348)
- netty 업그레이드 (#8346)
- snappy 버전 업그레이드 (#8494)
버그 수정 (Bug fixs)
- 복합 타입의 중첩 배열과 map이 올바르게 처리되지 않는 문제 (#9235)
- 빈 데이터 블록이 스키마를 반환하지 않는 문제 수정 (#9222)
- development webpack으로 mvn 빌드 허용; instances 기본값 수정 (#9179)
- reflection 스캐닝 클래스의 경쟁 조건 수정 (#9167)
- controller와 broker의 ingress 매니페스트 수정 (#9135)
- jvm 프로세서 수 수정 (#9138)
- grpc 쿼리 서버가 최대 인바운드 메시지 크기를 설정하지 않는 문제 수정 (#9126)
- upsert replace 수정 (#9132)
- 부분 upsert 레코드 읽기의 경쟁 조건 수정 (#9130)
- 하나의 매개변수 값이 누락된 로그 메시지 수정 (#9124)
- auth 애노테이션이 필요하지 않을 때 인증 문제 수정 (#9110)
- 서버 하위 쿼리를 깨뜨릴 수 있는 세그먼트 가지치기 수정 (#9090)
- ADLSGen2PinotFS의 NPE 수정 (#9088)
- cross merge 수정 (#9087)
- LaunchDataIngestionJobCommand auth 헤더 수정 (#9070)
- catalog 건너뛰기 수정 (#9069)
- InstanceConfig에서 URL을 가져오는 유틸 추가 수정 (#8856)
- MutableColumnStatistics의 문자열 길이 수정 (#9059)
- 테넌트용 인스턴스 상세 페이지 로딩 테이블 수정 (#9035)
- java 클라이언트의 스레드 안전성 문제 수정 (#8971)
- allSegmentLoaded 확인 수정 (#9010)
- segmentDetails 테이블 이름 파싱 버그 수정; 새 indexes 테이블 스타일링 (#8958)
- pulsar close 버그 수정 (#8913)
- REGEX OPTION 파서 수정 (#8905)
- 서버 지연에 음수 값 보고 방지 (#8892)
- MinionQuickstart의 getConfigOverrides 수정 (#8858)
- 세그먼트 생성 오류 처리 수정 (#8812)
- multi stage 엔진 serde 수정 (#8689)
- 서버 발견 수정 (#8664)
- 메트릭 집계를 확인하도록 Upsert 구성 검증 수정 (#8781)
- 다중값 컬럼 인덱스 생성 수정 (#8848)
- 여러 서버 퀵스타트의 grpc 포트 할당 수정 (#8834)
- 실시간 테이블 읽기를 위한 Spark 커넥터 GRPC 리더 수정 (#8824)
- minion용 auth 제공자 수정 (#8831)
- IngestionUtils의 메타데이터 push 모드 수정 (#8802)
- 업로드된 실시간 세그먼트의 세그먼트 검증 기타 수정 (#8786)
- ServerInstance.startQueryServer()의 오타 수정 (#8794)
- 서버가 쿼리 서버를 조기에 여는 문제 수정 (#8785)
- case 순서가 뒤집힌 회귀 수정, 회귀 테스트 추가 (#8748)
- 서버 재시작 또는 테이블 리로드 시 차원 테이블 로드 수정 (#8721)
- 두 개의 인덱스 필터 연산자가 있을 때 h3 inclusion 인덱스가 예외를 던지는 문제 수정 (#8707)
- 시간 경계 정보 읽기의 경쟁 조건 수정 (#8685)
- max/min/bloom에 의한 표현식 가지치기 수정 (#8672)
- 버킷을 직접 사용해 GcsPinotFs listFiles 수정 (#8656)
- 데이터 테이블의 컬럼 데이터 타입 저장 수정 (#8648)
- timestamp 인덱스 재작성의 잠재적 NPE 수정 (#8633)
- KinesisDataProducer의 타임아웃 문자열 형식 수정 (#8631)
- 레플리카 그룹 세그먼트 할당의 세그먼트 리밸런스 버그 수정 (#8598)
- 같은 비교 값을 가진 세그먼트 추가 시 upsert 메타데이터 버그 수정 (#8590)
- ClusterChangeMediator의 교착 상태 수정 (#8572)
- 음수 scale의 BigDecimal ser/de 수정 (#8553)
- 유효하지 않은 실시간 consumer props의 테이블 생성 버그 수정 (#8509)
- 수집 작업 파일시스템 스펙과 minion segmentNameGeneratorSpec에서 하위 props를 추출하는 점 누락 버그 수정 (#8511)
- 과중한 upsert 부하에서 쿼리 불일치 수정 (#7958 해결) (#7971)
- 여러 자식 스레드 사용 시 ChildTraceId 문제 수정, 고유하게 만들기 (#8443)
- 쿼리 타임아웃 시 group-by reduce 처리 수정 (#8450)
- BaseBrokerRequestHandler의 오타 수정 (#8448)
- 세그먼트 생성 중 TIMESTAMP 데이터 타입 사용 수정 (#8407)
- async-profiler 설치 수정 (#8404)
- 수집 transform 구성 버그 수정 (#8394)
- numDocs 읽기 전에 validDocIds 스냅샷으로 upsert 불일치 수정 (#8392)
- 다른 디렉터리에서 같은 이름의 파일 가져오기 버그 수정 (#8337)
- 누락된 NOT 처리 수정 (#8366)
- RealtimeSegmentConverter의 메트릭 압축 타입 설정 수정 (#8350)
- push 진행 중 세그먼트를 건너뛰도록 세그먼트 상태 체커 수정 (#8323)
- 다중 일 datetime truncate 수정 (#8327)
- access-token이 있는 경로의 리다이렉션 수정 (#8285)
- CSV 파일 주변 공백 문제 수정 (#9028)
- GrpcBrokerRequestHandler의 억제된 예외 수정 (#8272)