Docker에서 S3와 Pinot 사용하기
Docker에서 S3와 Pinot 사용하기
Docker에서 Pinot을 설정할 때 S3를 딥 스토어로 사용하는 방법을 알려드려요.
출처: 문서
본문
Pinot 클러스터 설정
Docker에서 Pinot을 S3를 딥 스토어로 사용하도록 설정하려면 Controller와 Server에 추가 config를 넣어야 해요.
Docker 네트워크 만들기
docker network create -d bridge pinot-demo
Zookeeper 시작
docker run \
--name zookeeper \
--restart always \
--network=pinot-demo \
-d zookeeper:3.9.5
Pinot 구성 파일 준비
아래 섹션들은 컨테이너에 마운트할 /tmp/pinot-s3-docker 아래 3개의 config 파일을 준비해요.
/tmp/pinot-s3-docker/
controller.conf
server.conf
ingestionJobSpec.yaml
Controller 시작
아래는 샘플 controller.conf 파일이에요.
controller.data.dir을 s3 버킷으로 구성하세요. 업로드된 모든 세그먼트가 거기에 저장돼요.
그리고 s3를 pinot 저장소로 추가하세요:
pinot.controller.storage.factory.class.s3=org.apache.pinot.plugin.filesystem.S3PinotFS pinot.controller.storage.factory.s3.region=us-west-2AWS 자격증명에 관해서는 DefaultAWSCredentialsProviderChain의 관례를 따르세요.
AccessKey와 Secret은 다음을 사용해 지정할 수 있어요:
- 환경 변수 -
AWS_ACCESS_KEY_ID와AWS_SECRET_ACCESS_KEY(.NET을 제외한 모든 AWS SDK와 CLI가 인식하므로 권장), 또는AWS_ACCESS_KEY와AWS_SECRET_KEY(Java SDK만 인식)- Java 시스템 속성 -
aws.accessKeyId와aws.secretKey- 모든 AWS SDK와 AWS CLI가 공유하는 기본 위치(
~/.aws/credentials)의 자격증명 프로필 파일- pinot config 파일에 AWS 자격증명 구성(예: config 파일에
pinot.controller.storage.factory.s3.accessKey와pinot.controller.storage.factory.s3.secretKey설정) (권장하지 않음)pinot.controller.storage.factory.s3.accessKey=****************LFVX pinot.controller.storage.factory.s3.secretKey=****************gfhz
pinot.controller.segment.fetcher.protocols에s3를 추가하고pinot.controller.segment.fetcher.s3.class를org.apache.pinot.common.utils.fetcher.PinotFSSegmentFetcher로 설정하세요.
pinot.role=controller
pinot.controller.storage.factory.class.s3=org.apache.pinot.plugin.filesystem.S3PinotFS
pinot.controller.storage.factory.s3.region=us-west-2
controller.data.dir=s3://<my-bucket>/pinot-data/pinot-s3-example-docker/controller-data/
controller.local.temp.dir=/tmp/pinot-tmp-data/
controller.helix.cluster.name=pinot-s3-example-docker
controller.zk.str=zookeeper:2181
controller.port=9000
controller.enable.split.commit=true
pinot.controller.segment.fetcher.protocols=file,http,s3
pinot.controller.segment.fetcher.s3.class=org.apache.pinot.common.utils.fetcher.PinotFSSegmentFetcher
그런 다음 다음으로 pinot controller를 시작하세요:
docker run --rm -ti \
--name pinot-controller \
--network=pinot-demo \
-p 9000:9000 \
--env AWS_ACCESS_KEY_ID=<aws-access-key-id> \
--env AWS_SECRET_ACCESS_KEY=<aws-secret-access-key> \
--mount type=bind,source=/tmp/pinot-s3-docker,target=/tmp \
apachepinot/pinot:1.5.1 StartController \
-configFileName /tmp/controller.conf
Broker 시작
Broker는 간단하므로 기본값으로 시작하면 돼요:
docker run --rm -ti \
--name pinot-broker \
--network=pinot-demo \
--env AWS_ACCESS_KEY_ID=<aws-access-key-id> \
--env AWS_SECRET_ACCESS_KEY=<aws-secret-access-key> \
apachepinot/pinot:1.5.1 StartBroker \
-zkAddress zookeeper:2181 -clusterName pinot-s3-example-docker
Server 시작
아래는 샘플 server.conf 파일이에요.
controller config와 유사하게 pinot server에도 s3 config를 설정하세요.
pinot.server.netty.port=8098
pinot.server.adminapi.port=8097
pinot.server.instance.dataDir=/tmp/pinot-tmp/server/index
pinot.server.instance.segmentTarDir=/tmp/pinot-tmp/server/segmentTars
pinot.server.storage.factory.class.s3=org.apache.pinot.plugin.filesystem.S3PinotFS
pinot.server.storage.factory.s3.region=us-west-2
pinot.server.segment.fetcher.protocols=file,http,s3
pinot.server.segment.fetcher.s3.class=org.apache.pinot.common.utils.fetcher.PinotFSSegmentFetcher
그런 다음 다음으로 pinot server를 시작하세요:
docker run --rm -ti \
--name pinot-server \
--network=pinot-demo \
--env AWS_ACCESS_KEY_ID=<aws-access-key-id> \
--env AWS_SECRET_ACCESS_KEY=<aws-secret-access-key> \
--mount type=bind,source=/tmp/pinot-s3-docker,target=/tmp \
apachepinot/pinot:1.5.1 StartServer \
-zkAddress zookeeper:2181 -clusterName pinot-s3-example-docker \
-configFileName /tmp/server.conf
테이블 설정
이 데모에서는 docker 이미지 안에 이미 패키징된 airlineStats 테이블을 예시로 사용해요.
테이블 conf와 schema 파일을 컨테이너에 마운트해 실행할 수도 있어요.
docker run --rm -ti \
--name pinot-ingestion-job \
--network=pinot-demo \
apachepinot/pinot:1.5.1 AddTable \
-controllerHost pinot-controller \
-controllerPort 9000 \
-schemaFile examples/batch/airlineStats/airlineStats_schema.json \
-tableConfigFile examples/batch/airlineStats/airlineStats_offline_table_config.json \
-exec
수집 작업 설정 (Ingestion Jobs)
Standalone 작업
특정 변경 사항이 있는 샘플 standalone 수집 job spec은 다음과 같아요:
-
jobType은 SegmentCreationAndMetadataPush (이 작업은 controller 세그먼트 다운로드를 우회)
-
inputDirURI는 s3 위치 **s3://my.bucket/batch/airlineStats/rawdata/**로 설정
-
outputDirURI는 s3 위치 s3://my.bucket/output/airlineStats/segments로 설정
-
pinotFSSpecs 아래에 새 PinotFs 추가
- scheme: s3 className: org.apache.pinot.plugin.filesystem.S3PinotFS configs: region: 'us-west-2'
샘플 ingestionJobSpec.yaml:
# executionFrameworkSpec: 실행할 수집 작업 정의
executionFrameworkSpec:
# name: 실행 프레임워크 이름
name: 'standalone'
# segmentGenerationJobRunnerClassName: org.apache.pinot.spi.batch.ingestion.runner.SegmentGenerationJobRunner 인터페이스를 구현하는 클래스 이름
segmentGenerationJobRunnerClassName: 'org.apache.pinot.plugin.ingestion.batch.standalone.SegmentGenerationJobRunner'
# segmentTarPushJobRunnerClassName: org.apache.pinot.spi.batch.ingestion.runner.SegmentTarPushJobRunner 인터페이스를 구현하는 클래스 이름
segmentTarPushJobRunnerClassName: 'org.apache.pinot.plugin.ingestion.batch.standalone.SegmentTarPushJobRunner'
# segmentUriPushJobRunnerClassName: org.apache.pinot.spi.batch.ingestion.runner.SegmentUriPushJobRunner 인터페이스를 구현하는 클래스 이름
segmentUriPushJobRunnerClassName: 'org.apache.pinot.plugin.ingestion.batch.standalone.SegmentUriPushJobRunner'
# segmentMetadataPushJobRunnerClassName: org.apache.pinot.spi.batch.ingestion.runner.IngestionJobRunner 인터페이스를 구현하는 클래스 이름
segmentMetadataPushJobRunnerClassName: 'org.apache.pinot.plugin.ingestion.batch.standalone.SegmentMetadataPushJobRunner'
# jobType: Pinot 수집 작업 유형
# 지원되는 job 유형:
# 'SegmentCreation'
# 'SegmentTarPush'
# 'SegmentUriPush'
# 'SegmentCreationAndTarPush'
# 'SegmentCreationAndUriPush'
jobType: SegmentCreationAndMetadataPush
# inputDirURI: 입력 데이터의 루트 디렉터리, PinotFS에 구성된 scheme 있어야 함
inputDirURI: 's3://<my-bucket>/pinot-data/rawdata/airlineStats/rawdata/'
# includeFileNamePattern: 포함할 파일 이름 패턴, 전역 glob 패턴 지원
# 샘플 사용법:
# 'glob:*.avro'는 inputDirURI 바로 아래의 avro 파일만 포함, 하위 디렉터리는 제외
# 'glob:**/*.avro'는 inputDirURI 아래의 모든 avro 파일을 재귀적으로 포함
includeFileNamePattern: 'glob:**/*.avro'
# excludeFileNamePattern: 제외할 파일 이름 패턴, 전역 glob 패턴 지원
# 샘플 사용법:
# 'glob:*.avro'는 inputDirURI 바로 아래의 avro 파일만 제외, 하위 디렉터리는 제외
# 'glob:**/*.avro'는 inputDirURI 아래의 모든 avro 파일을 재귀적으로 제외
# _excludeFileNamePattern: ''
# outputDirURI: 출력 세그먼트의 루트 디렉터리, PinotFS에 구성된 scheme 있어야 함
outputDirURI: 's3://<my-bucket>/pinot-data/pinot-s3-docker/segments/airlineStats'
# segmentCreationJobParallelism: 세그먼트 생성 병렬도
segmentCreationJobParallelism: 5
# overwriteOutput: 기존 출력 세그먼트 덮어쓰기 여부
overwriteOutput: true
# pinotFSSpecs: 모든 관련 Pinot 파일 시스템 정의
pinotFSSpecs:
- # scheme: PinotFS 식별에 사용
# 예: local, hdfs, dbfs 등
scheme: file
# className: PinotFS 인스턴스 생성에 사용되는 클래스 이름
# 예:
# org.apache.pinot.spi.filesystem.LocalPinotFS는 로컬 파일시스템용
# org.apache.pinot.plugin.filesystem.AzurePinotFS는 Azure Data Lake용
# org.apache.pinot.plugin.filesystem.HadoopPinotFS는 HDFS용
className: org.apache.pinot.spi.filesystem.LocalPinotFS
- scheme: s3
className: org.apache.pinot.plugin.filesystem.S3PinotFS
configs:
region: 'us-west-2'
# recordReaderSpec: 모든 record reader 정의
recordReaderSpec:
# dataFormat: 레코드 데이터 형식, 예: 'avro', 'parquet', 'orc', 'csv', 'json', 'thrift'
dataFormat: 'avro'
# className: 해당 RecordReader 클래스 이름
# 예:
# org.apache.pinot.plugin.inputformat.avro.AvroRecordReader
# org.apache.pinot.plugin.inputformat.csv.CSVRecordReader
# org.apache.pinot.plugin.inputformat.parquet.ParquetRecordReader
# org.apache.pinot.plugin.inputformat.json.JSONRecordReader
# org.apache.pinot.plugin.inputformat.orc.ORCRecordReader
# org.apache.pinot.plugin.inputformat.thrift.ThriftRecordReader
className: 'org.apache.pinot.plugin.inputformat.avro.AvroRecordReader'
# tableSpec: 테이블 이름과 해당 테이블 config 및 schema를 가져올 위치 정의
tableSpec:
# tableName: 테이블 이름
tableName: 'airlineStats'
# schemaURI: 테이블 스키마를 읽을 위치 정의, PinotFS 또는 HTTP 지원
# 예:
# hdfs://path/to/table_schema.json
# http://localhost:9000/tables/myTable/schema
schemaURI: 'http://pinot-controller:9000/tables/airlineStats/schema'
# tableConfigURI: 테이블 config를 읽을 위치 정의
# PinotFS 또는 HTTP 지원
# 예:
# hdfs://path/to/table_config.json
# http://localhost:9000/tables/myTable
# 참고: pinot controller에서 Pinot 테이블 config를 직접 읽는 API는 JSON wrapper를 포함
# 실제 테이블 config는 'OFFLINE' 필드 아래의 객체
tableConfigURI: 'http://pinot-controller:9000/tables/airlineStats'
# pinotClusterSpecs: Pinot 클러스터 접근 지점 정의
pinotClusterSpecs:
- # controllerURI: 테이블/스키마 정보와 데이터 push에 사용
# 예: http://localhost:9000
controllerURI: 'http://pinot-controller:9000'
# pushJobSpec: 세그먼트 push 작업 관련 구성 정의
pushJobSpec:
# pushAttempts: push 작업 시도 횟수, 기본값 1(재시도 없음)
pushAttempts: 2
# pushRetryIntervalMillis: 재시도 대기 ms, 기본값 1초
pushRetryIntervalMillis: 1000
데이터 수집 작업을 실행하세요:
docker run --rm -ti \
--name pinot-ingestion-job \
--network=pinot-demo \
--env AWS_ACCESS_KEY_ID=<aws-access-key-id> \
--env AWS_SECRET_ACCESS_KEY=<aws-secret-access-key> \
--mount type=bind,source=/tmp/pinot-s3-docker,target=/tmp \
apachepinot/pinot:1.5.1 LaunchDataIngestionJob \
-jobSpecFile /tmp/ingestionJobSpec.yaml