입력 형식 플러그인
입력 형식 플러그인 (Input Format Plugin)
Pinot의 입력 형식 플러그인을 다루는 문서예요. Pinot는 배치 수집을 위해 여러 입력 형식을 기본으로 지원해요. 실시간 수집의 경우 현재 JSON만 지원돼요. 그러나 Pinot의 플러그 가능한 아키텍처 덕분에 표준 인터페이스를 구현해 어떤 형식이든 쉽게 사용할 수 있어요.
출처: 문서
본문
Pinot는 배치 수집을 위해 여러 입력 형식을 기본으로 지원해요. 실시간 수집은 현재 JSON만 지원돼요. 그러나 Pinot의 플러그 가능한 아키텍처 덕분에 표준 인터페이스를 구현하면 어떤 형식이든 쉽게 사용할 수 있어요.
배치 레코드 판독기 플러그인 (Batch Record Reader Plugin)
Pinot가 지원하는 모든 배치 입력 형식은 RecordReader를 사용해 데이터를 역직렬화해요. RecordReader와 RecordExtractor 인터페이스를 구현해 자체 파일 형식 지원을 추가할 수도 있어요.
파일을 Pinot 세그먼트로 인덱싱하려면 인터페이스를 구현해 인덱스 엔진 - SegmentIndexCreationDriverImpl에 끼워 넣어요. Pinot는 파일을 세그먼트로 인덱싱할 때 2-패스 알고리즘을 사용하므로 레코드 판독기에 rewind() 메서드가 필요해요.
일반 행 (Generic Row)
GenericRow는 인덱스 엔진이 읽고 인덱싱할 수 있는 레코드 추상화예요. 컬럼 이름(String)에서 컬럼 값(Object)으로의 맵이에요. 다중 값 컬럼의 경우 값은 객체 배열(Object[])이어야 해요.
BaseRecordExtractor를 확장하면 공유 변환 디스패처가 아닌 공유 스캐폴딩으로 취급해요. init()은 include 목록을 _extractAll과 _fields로 해석한 다음, 추출기 특정 설정을 위해 initConfig()를 호출하고, stringifyMapKey()는 Map<String, Object> 계약을 위한 공유 헬퍼예요.
각 구체 추출기는 이제 자신의 변환 로직을 소유하지만 여전히 RecordExtractor 계약을 충족해야 해요. 가능하면 지원 스칼라 타입을 네이티브 Java 형태로 보존하고, 다중 값 필드는 Object[]를, 중첩 레코드나 맵은 Map<String, Object>를 내보내고, 소스 필드가 설정되지 않았을 때는 null을 보존해요. 소스 형식이 String이 아닌 맵 키를 노출할 수 있다면 GenericRow에 쓰기 전에 stringifyMapKey()를 호출해요.
레코드 판독기 계약 (Contracts for Record Reader)
자체 레코드 판독기를 구현할 때 개발자가 따라야 할 몇 가지 계약이 있어요:
- 출력 GenericRow는 제공된 테이블 스키마를 따라야 해요:
- 스키마의 모든 컬럼이 보존되어야 함 (원본 레코드에 컬럼이 없으면 기본값을 넣음)
- 스키마에 없는 컬럼은 포함되지 않아야 함
- 컬럼 값은 스키마의 필드 스펙을 따라야 함 (데이터 타입, 단일값/다중값)
- 시간 컬럼(일반적으로 DateTimeFieldSpec으로 정의; 레거시 스키마는 여전히
TimeFieldSpec을 역직렬화할 수 있음)의 경우, 레코드 판독기는 들어오는 시간과 나가는 시간을 모두 읽을 수 있어야 해요 (인덱스 생성 중 들어오는 시간 - 원본 데이터의 시간 값에서 나가는 시간 - Pinot에 저장된 시간 값으로의 변환을 허용해요).- 들어오는·나가는 시간 컬럼 이름이 같으면 들어오는 시간 필드 스펙을 사용
- 들어오는·나가는 시간 컬럼 이름이 다르면 둘 다 시간 필드 스펙으로 넣음
- 이미 변환된 시간 값을 포함한 입력 파일을 처리하기 위해 들어오는·나가는 시간 컬럼을 모두 유지해요
스트림 디코더 플러그인 (Stream Decoder Plugin)
Pinot는 디코더를 사용해 실시간 스트림에서 사용 가능한 데이터를 파싱해요. 디코더는 스트림의 바이너리 데이터를 GenericRow 객체로 변환하는 책임을 져요.
StreamMessageDecoder 인터페이스를 구현해 자체 디코더를 작성할 수 있어요. 파싱된 객체에서 GenericRow로 필드를 추출하기 위해 배치 입력 형식의 RecordExtractor를 사용할 수도 있어요.