본문으로 건너뛰기
최종 수정: 에

데이터 적재 모범 사례 및 성능 튜닝

데이터 적재는 Apache Doris의 가장 중요한 기능 중 하나입니다. 데이터 적재 효율은 실시간 분석의 적시성과 시스템 안정성을 직접적으로 좌우합니다. 이 문서에서는 일반적인 비즈니스 시나리오를 바탕으로 바로 적용할 수 있는 모범 사례를 먼저 소개한 다음, 데이터 적재의 내부 동작과 튜닝 방법을 자세히 살펴봅니다. 이를 통해 다음을 수행할 수 있습니다.

  • 비즈니스 특성에 맞는 데이터 적재 방식 선택
  • 테이블 설계, 배치 처리, 버킷팅, 메모리 및 동시성에 대한 합리적인 결정
  • 빈번한 소량 데이터 적재, 쓰기 증폭, Memtable OOM과 같은 일반적인 문제 방지
  • 비즈니스에 맞는 지연 시간과 처리량의 균형점 찾기

빠른 탐색​

고려 사항권장 방법관련 절
데이터 적재 방식 선택데이터 소스와 실시간 요구 사항에 따라 선택적절한 데이터 적재 방식 선택
테이블 모델Duplicate Key 모델 우선 사용테이블 모델과 인덱스
파티셔닝과 버킷팅단일 Tablet 크기를 1~10 GB로 유지파티셔닝 및 버킷팅 구성
랜덤 버킷팅load_to_single_tablet을 활성화하여 처리량 향상랜덤 버킷팅 데이터 적재 최적화
빈번한 소량 데이터 적재클라이언트 측 배치 처리와 Group Commit 병행배치 처리 전략
데이터 적재당 파티션 수Memtable이 너무 많아지지 않도록 적은 수로 제한파티션 데이터 적재와 메모리 제어
대용량 데이터 적재배치로 나누고 각 배치를 100 GB 이하로 제한대규모 데이터 배치 적재
Broker Load 동시성압축 파일이나 컬럼형 파일을 분할하여 동시 처리Broker Load 동시성
Stream Load 동시성BE당 동시성을 128 미만으로 유지Stream Load 동시성

적절한 데이터 적재 방식 선택​

Doris는 핵심 워크플로를 공유하면서도 서로 다른 시나리오에 최적화된 여러 데이터 적재 방식을 제공합니다. 데이터 소스와 비즈니스 요구 사항에 따라 선택하세요.

데이터 적재 방식프로토콜실행 모드일반적인 데이터 소스적용 시나리오
Stream LoadHTTP동기로컬 파일, 데이터 스트림실시간 쓰기(예: 애플리케이션에서 푸시하는 데이터)
Broker LoadSQL비동기HDFS, S3 및 기타 외부 스토리지대규모 배치 데이터 적재
Routine LoadSQL비동기 스트리밍KafkaExactly-Once를 지원하는 메시지 큐 데이터의 실시간 동기화
Insert Into / SelectSQL동기/비동기Doris 테이블, Hive, MySQL, S3 TVFETL 작업, 외부 데이터 통합
MySQL LoadMySQL LOAD DATA동기로컬 CSV 파일MySQL 사용자의 소규모 테스트 또는 마이그레이션(FE가 Stream Load로 전달)

데이터 적재 모범 사례​

다음 절에서는 데이터 적재 시 자주 고려하는 사항을 살펴보고 바로 적용할 수 있는 모범 사례를 소개합니다.

테이블 모델과 인덱스​

테이블 모델 선택​

Duplicate Key 모델을 우선 사용하세요.

  • 집계나 중복 제거 없이 원시 데이터만 저장하므로 데이터 적재 경로가 가장 짧습니다.
  • 데이터 적재 성능과 쿼리 성능 모두 다른 모델보다 뛰어납니다.
  • Aggregate 모델은 Key 컬럼을 기준으로 집계해야 하고, Unique Key 모델은 중복을 제거해야 합니다. 두 모델 모두 MemTable 단계에서 BE 측의 추가 연산(정렬, 중복 제거)이 필요하므로 CPU와 메모리 사용량이 증가합니다.

Key를 기준으로 집계하거나 중복을 제거해야 하는 경우에만 Aggregate 또는 Unique Key 모델을 선택하세요. 자세한 내용은 데이터 모델을 참조하세요.

인덱스 관리​

인덱스(예: 비트맵 인덱스, 역색인)는 데이터 적재 중에 동기적으로 갱신해야 하므로 쓰기 시 유지 관리 비용이 증가합니다. 다음을 권장합니다.

  • 자주 쿼리하는 필드에만 인덱스를 생성하세요.
  • 중복 인덱스를 피하여 쓰기 중 BE에서 수행하는 인덱스 생성과 검증을 줄이세요. 이렇게 하면 CPU와 메모리 사용량을 낮추고 데이터 적재 처리량을 높일 수 있습니다.

파티셔닝 및 버킷팅 구성​

파티셔닝과 버킷팅은 BE 노드 간 데이터 분산 방식과 병렬 처리 수준을 결정하며, 데이터 적재 및 쿼리 성능에 직접적인 영향을 미칩니다.

단일 Tablet 크기: 1-10 GB​

단일 Tablet 크기를 1~10 GB 범위로 유지하세요.

Tablet 크기영향
너무 작음집계 효과 저하, 메타데이터 관리 부담 증가
너무 큼복제본 마이그레이션과 보충이 어려움
1-10 GB(권장)데이터 적재, 쿼리, 복제본 관리 사이의 균형 유지

버킷 수 계산식: bucket count = total data size / (1-10 GB). 적절한 버킷 키(예: 임의의 컬럼)와 함께 사용하면 데이터 편향을 방지하고, BE 노드 간 부하를 균등하게 분산하며, 병렬 쓰기 효율을 높일 수 있습니다.

자세한 내용은 데이터 분산을 참조하세요.

파티션 설계: 데이터 분산 및 메모리 부담 감소​

비즈니스의 쿼리 패턴(예: 시간 또는 지역)에 따라 파티션을 나누세요. 그러면 데이터 적재 중 대상 파티션에만 데이터를 분산하여 관련 없는 파티션의 메타데이터와 파일을 처리하지 않을 수 있습니다. 또한 다음 사항을 고려해야 합니다.

  • 여러 파티션에 동시에 쓰면 많은 Tablet이 활성화됩니다. 각 Tablet은 자체 MemTable을 사용하므로 BE의 메모리 부담이 크게 증가합니다.
  • 메모리가 부족하면 조기 Flush가 발생하여 작은 Segment 파일이 많이 생성되고, 이로 인해 Compaction이 빈번해지고 쓰기 증폭이 발생합니다.

활성 파티션 수를 제한하면(예: 하루 단위로 데이터 적재) 동시에 활성화되는 Tablet 수와 메모리 부담을 줄이고, 더 큰 Segment 파일을 생성하며, Compaction 부하를 낮출 수 있습니다. 이를 통해 병렬 쓰기 효율과 이후의 쿼리 성능을 개선할 수 있습니다.

랜덤 버킷팅 데이터 적재 최적화​

랜덤 버킷팅을 사용할 때는 load_to_single_tablet=true로 설정하여 단일 Tablet 데이터 적재 모드를 활성화할 수 있습니다.

  • 데이터를 여러 Tablet에 분산하지 않고 단일 Tablet에 직접 씁니다. 따라서 Tablet 분산 계산에 필요한 CPU 오버헤드와 BE 간 RPC 전송 오버헤드를 없앨 수 있습니다.
  • 쓰기를 단일 Tablet에 집중하면 작은 Segment 파일의 생성을 줄이고 빈번한 Compaction으로 인한 쓰기 증폭을 방지할 수 있습니다.
  • 대규모 데이터 적재의 동시성과 처리량이 크게 향상됩니다.

자세한 내용은 랜덤 버킷팅을 참조하세요.

배치 처리 전략​

각 데이터 적재는 독립적인 트랜잭션으로, FE Edit Log 쓰기(메타데이터 변경 기록)와 BE MemTable의 디스크 플러시(Segment 파일 생성)를 수반합니다. 빈번한 소규모 배치 데이터 적재(KB 수준)는 다음 문제를 일으킵니다.

  • FE Edit Log 쓰기가 빈번해져 FE 디스크 I/O가 증가합니다.
  • BE MemTable 플러시가 빈번해져 작은 Segment 파일이 많이 생성됩니다.
  • Compaction이 빈번해져 심각한 쓰기 증폭이 발생합니다.

클라이언트 측과 서버 측 배치 처리를 병행하여 이 문제를 완화할 수 있습니다.

배치 처리 방식적용 시나리오권장 방법
클라이언트 측 배치 처리클라이언트가 제어하는 배치 쓰기클라이언트에서 데이터를 수백 MB~수 GB까지 모은 후 데이터 적재를 시작하세요. 여러 소규모 트랜잭션을 하나의 대규모 트랜잭션으로 대체하면 FE Edit Log 쓰기와 BE MemTable 플러시 빈도를 줄여 스토리지 단편화와 후속 Compaction의 리소스 소비를 방지할 수 있습니다.
서버 측 배치 처리(Group Commit)동시성이 높고 데이터양이 적은 데이터 적재Group Commit을 활성화하면 서버가 짧은 시간 구간 내의 여러 소규모 배치를 하나의 트랜잭션으로 병합합니다. 병합된 대규모 트랜잭션은 더 큰 Segment 파일을 생성하고 백그라운드 Compaction 부담을 줄입니다. 로그 및 IoT 데이터처럼 소규모 배치를 빈번하게 처리하는 시나리오에 특히 적합합니다.

파티션 데이터 적재와 메모리 제어​

데이터 적재 중 BE는 먼저 메모리 내 MemTable(기본값 200 MB)에 데이터를 씁니다. MemTable이 가득 차면 디스크로 비동기 플러시하여 Segment 파일을 생성합니다. 각 Tablet은 메모리에 하나의 활성 MemTable을 가지므로, 단일 데이터 적재가 포함하는 파티션 수는 메모리 사용량에 직접적인 영향을 미칩니다.

  1. 파티션이 너무 많으면 활성 Tablet과 활성 MemTable이 많아져 메모리 사용량이 증가합니다.
  2. 메모리 사용량이 너무 높으면 프로세스 OOM을 방지하기 위해 조기 플러시가 발생합니다.
  3. 조기 플러시는 작은 파일을 많이 생성하여 데이터 적재 성능을 더욱 저하시킵니다.

안정적인 데이터 적재 처리량을 확보하려면 다음을 따르세요.

  • 파티션을 순서대로 데이터 적재: 예를 들어 하루 단위로 데이터 적재를 수행하여 데이터 쓰기를 단일 파티션에 집중시키면 MemTable의 분산과 플러시 횟수를 줄이고, 메모리 단편화와 I/O 부담을 낮출 수 있습니다.
  • 단일 데이터 적재가 포함하는 파티션 수를 엄격하게 제어하여 과도한 MemTable로 인한 조기 플러시를 방지하세요.

대규모 데이터 배치 적재​

파일 수가 많고 데이터양이 매우 클 때는 배치로 나누어 데이터 적재를 수행하세요. 재시도 비용을 줄이고 BE 메모리와 디스크에 부하가 집중되는 것을 방지할 수 있습니다.

데이터 소스권장 데이터 적재 방식권장 배치 크기
HDFS 또는 오브젝트 스토리지 등의 원격 파일Broker Load각 배치를 100 GB 이하로 제한
대용량 로컬 파일Doris streamloader 도구(자동 배치 처리)도구가 자동으로 제어

Broker Load 동시성​

파일 유형에 따라 동시성 전략이 달라집니다.

  • 압축 파일 / Parquet / ORC 파일: 데이터 적재 전에 여러 개의 작은 파일로 분할하여 동시에 데이터 적재를 수행할 수 있도록 하세요.
  • 압축되지 않은 CSV 및 JSON 파일: Doris가 내부적으로 파일을 자동 분할하여 동시에 데이터 적재를 수행합니다.

동시성 전략은 Broker Load 구성 매개변수를 참조하세요.

Stream Load 동시성​

Stream Load 동시성은 BE 스레드 풀 매개변수의 제한을 받습니다. 다음 임계값을 따르세요.

매개변수 / 임계값권장 값설명
BE당 동시성(권장 상한)128 이하BE의 webserver_num_workers로 제어합니다. 이를 초과하면 웹 서버 스레드가 고갈되고 데이터 적재 성능이 저하될 수 있습니다.
BE당 동시성(하드 제한)512를 초과하면 안 됨doris_max_remote_scanner_thread_pool_thread_num으로 제어합니다. 이를 초과하면 BE 프로세스가 응답하지 않을 수 있습니다.

지연 시간이 짧아야 하는 시나리오의 동시성 절충​

실시간 모니터링처럼 지연 시간이 짧아야 하는 시나리오에서는 다음을 따르세요.

  • 리소스 경합을 방지하도록 동시성을 적절히 낮추세요.
  • Group Commit의 비동기 모드(async_mode)를 함께 사용하여 소규모 트랜잭션을 병합하고 트랜잭션 커밋 지연 시간을 줄이세요.

Doris 데이터 적재 내부 동작 자세히 살펴보기​

다음 내부 동작을 이해하면 복잡한 시나리오에서 더 나은 튜닝 결정을 내릴 수 있습니다.

설계 철학​

Doris 데이터 적재는 분산 아키텍처를 기반으로 하며, 주로 Frontend(FE)와 Backend(BE) 노드가 관여합니다.

  • FE: 메타데이터 관리, 쿼리 구문 분석, 작업 스케줄링, 트랜잭션 조정을 담당합니다.
  • BE: 실제 데이터 저장, 연산, 쓰기 작업을 담당합니다.

데이터 적재 설계는 실시간 쓰기, 스트리밍 동기화, 배치 데이터 적재, 외부 데이터 소스 통합 등 다양한 비즈니스 요구를 충족하는 것을 목표로 합니다. 핵심 원칙은 다음과 같습니다.

설계 목표구현 방식
일관성과 원자성각 데이터 적재 작업을 하나의 트랜잭션으로 처리하여 데이터 쓰기의 원자성을 보장하고 부분 쓰기를 방지합니다. Label 메커니즘으로 데이터 손실이나 중복을 방지합니다.
유연성다양한 데이터 소스(로컬 파일, HDFS, S3, Kafka 등)와 형식(CSV, JSON, Parquet, ORC 등)을 지원하여 여러 시나리오에 대응합니다.
효율성분산 아키텍처를 활용하여 데이터를 병렬로 처리하고, 여러 BE 노드가 동시에 데이터를 처리하여 처리량을 높입니다.
간편함경량 ETL 기능을 제공하여 데이터 적재 중에 데이터를 정제하고 변환할 수 있으므로 외부 도구에 대한 의존도를 줄입니다.
유연한 모델링Duplicate Key, Unique Key, Aggregate Key 모델을 지원하여 데이터 적재 중에 집계하거나 중복을 제거할 수 있습니다.

공통 데이터 적재 워크플로​

데이터 적재 방식(Stream Load, Broker Load, Routine Load 등)에 관계없이 핵심 워크플로는 기본적으로 동일합니다.

  1. 데이터 적재 작업 제출

    1. 클라이언트(예: HTTP, JDBC 또는 MySQL 클라이언트)를 통해 데이터 적재 요청을 제출하며, 데이터 소스(예: 로컬 파일, Kafka 토픽 또는 HDFS 파일 경로), 대상 테이블, 파일 형식, 데이터 적재 매개변수(예: 구분자 및 오류 허용 범위)를 지정합니다.
    2. 각 작업에는 고유한 Label을 지정하여 작업을 식별하고 멱등성을 지원할 수 있습니다(중복 데이터 적재 방지). 예를 들어 Stream Load에서는 HTTP 헤더를 통해 Label을 지정합니다.
    3. Doris Frontend(FE)가 요청을 받아 권한을 검증하고, 대상 테이블의 존재 여부를 확인하며, 데이터 적재 매개변수를 분석합니다.
  2. 작업 할당 및 조정

    1. FE는 테이블의 파티셔닝 및 버킷팅 규칙에 따라 데이터 분산을 분석하고, 데이터 적재 계획을 생성한 다음, 전체 작업을 조정할 Coordinator로 Backend(BE) 노드를 선택합니다.
    2. Stream Load처럼 BE에 직접 요청을 제출하면 해당 BE가 Coordinator 역할을 할 수 있지만, 여전히 FE에서 메타데이터(예: 테이블 스키마)를 가져와야 합니다.
    3. 데이터 적재 계획은 효율을 높이기 위해 데이터를 여러 BE 노드에 분산하여 병렬 처리를 보장합니다.
  3. 데이터 읽기 및 분산

    1. Coordinator BE가 데이터 소스에서 데이터를 읽습니다(예: Kafka에서 메시지 가져오기, S3에서 파일 읽기 또는 HTTP 데이터 스트림 직접 수신).
    2. Doris는 데이터 형식을 분석하며(예: CSV 분할 또는 JSON 파싱), 다음과 같은 사용자 정의 경량 ETL 작업을 지원합니다.
      • 사전 필터링: 원시 데이터를 필터링하여 처리 오버헤드를 줄입니다.
      • 컬럼 매핑: 소스 컬럼과 대상 테이블 컬럼 간의 대응 관계를 조정합니다.
      • 데이터 변환: 표현식을 사용하여 데이터를 처리합니다.
      • 사후 필터링: 변환된 데이터를 필터링합니다.
    3. 분석이 끝나면 Coordinator BE가 파티셔닝 및 버킷팅 규칙에 따라 여러 하위 Executor BE에 데이터를 분산합니다.
  4. 데이터 쓰기

    1. 데이터는 여러 BE 노드에 분산되어 메모리 내 테이블(MemTable)에 기록되고 Key 컬럼을 기준으로 정렬됩니다. Aggregate 또는 Unique Key 모델에서는 Doris가 Key를 기준으로 집계하거나 중복을 제거합니다(SUM, REPLACE 등 사용).
    2. MemTable이 가득 차거나(기본값 200 MB) 작업이 끝나면 데이터를 디스크에 비동기적으로 기록하여 Rowset을 구성하는 컬럼형 Segment 파일을 생성합니다.
    3. 각 BE는 할당된 데이터를 독립적으로 처리하고, 쓰기가 완료되면 Coordinator에 상태를 보고합니다.
  5. 트랜잭션 커밋 및 게시

    1. Coordinator가 FE에 트랜잭션 커밋(Commit)을 요청합니다. FE는 과반수의 복제본에서 쓰기가 성공했음을 확인한 후 BE에 데이터 버전 게시(Publish Version)를 알립니다. BE의 Publish가 성공하면 FE가 트랜잭션을 VISIBLE로 표시하며 데이터를 쿼리할 수 있게 됩니다.
    2. 실패하면 FE가 롤백을 수행하여 임시 데이터를 제거하고 데이터 일관성을 보장합니다.
  6. 결과 반환

    1. 동기 방식(예: Stream Load, Insert Into)은 성공/실패 상태와 오류 세부 정보(예: ErrorURL)를 포함한 데이터 적재 결과를 직접 반환합니다.
    2. 비동기 방식(예: Broker Load)은 작업 ID와 Label을 반환합니다. SHOW LOAD를 사용하여 진행 상황, 오류 행 수, 상세 정보를 확인할 수 있습니다.
    3. 작업은 추후 추적할 수 있도록 감사 로그에 기록됩니다.

MemTable 포워딩​

MemTable 포워딩은 Apache Doris 2.1.0에서 도입된 최적화로, INSERT INTO...SELECT 데이터 적재 성능을 크게 개선합니다.

  • 기존 흐름의 병목: Sink 노드는 데이터를 Block 형식으로 인코딩하고 Ping-pong RPC를 통해 하위 노드로 전송해야 합니다. 이 과정에서 여러 차례 인코딩과 디코딩이 수행되어 오버헤드가 증가합니다.
  • 최적화: Sink 노드가 MemTable을 직접 처리하고 Segment 데이터를 생성한 후 Streaming RPC로 전송합니다. 이를 통해 인코딩/디코딩과 전송 대기를 줄이고 메모리 역압을 더 정확하게 제어할 수 있습니다.
  • 성능 향상: 공식 테스트에서 데이터 적재 시간이 단일 복제본 시나리오에서는 기존의 36%, 복제본 세 개 시나리오에서는 54%로 줄었으며, 전체 성능은 100% 이상 향상되었습니다.
  • 적용 범위: 현재 이 기능은 스토리지와 컴퓨팅이 통합된 배포 모드에서만 지원됩니다.

컴퓨팅-스토리지 분리형 아키텍처의 데이터 적재​

컴퓨팅-스토리지 분리형 아키텍처에서는 데이터 저장과 트랜잭션 관리를 분리하는 데 데이터 적재 최적화의 초점을 맞춥니다.

  • 데이터 저장
    • BE는 데이터를 영구 저장하지 않습니다. MemTable Flush 후 생성된 Segment 파일을 공유 스토리지(예: S3 또는 HDFS)에 직접 업로드하여 오브젝트 스토리지의 높은 가용성과 낮은 비용을 활용하고 탄력적인 확장을 지원합니다.
    • BE의 로컬 File Cache는 자주 사용하는 데이터를 비동기적으로 캐싱하고, TTL 및 Warmup 전략을 통해 쿼리 캐시 적중률을 높입니다.
    • 메타데이터(예: Tablet 및 Rowset 메타데이터)는 BE의 로컬 RocksDB 대신 Meta Service가 FoundationDB에 저장합니다.
  • 트랜잭션 처리
    • 트랜잭션 관리를 FE에서 Meta Service로 이전하여 FE Edit Log 쓰기 병목을 제거합니다.
    • Meta Service는 표준 인터페이스(beginTransaction, commitTransaction)를 통해 트랜잭션을 관리하며, FoundationDB의 전역 트랜잭션 기능을 기반으로 일관성을 보장합니다.
    • BE Coordinator는 Meta Service와 직접 상호 작용하여 트랜잭션 상태를 기록하고, 원자적 연산으로 충돌과 시간 초과에 따른 회수를 처리합니다. 이를 통해 동기화 로직을 단순화하고 동시성이 높은 소규모 배치 데이터 적재의 처리량을 높입니다.

지연 시간과 처리량 사이의 절충​

실제 비즈니스 시나리오에서는 데이터 적재의 지연 시간과 처리량 사이에서 균형을 맞춰야 하는 경우가 많습니다.

  • 더 짧은 지연 시간: 최신 데이터를 더 빨리 확인할 수 있지만, 쓰기 배치가 작아지고 쓰기 빈도가 높아지면 백그라운드 Compaction이 더 자주 발생합니다. 이로 인해 CPU, I/O, 메모리 소비가 늘어나고 메타데이터 관리 부담이 증가합니다.
  • 더 높은 처리량: 데이터 적재당 데이터양을 늘리고 데이터 적재 횟수를 줄이면 메타데이터 부담과 백그라운드 Compaction 오버헤드를 크게 낮춰 전체 시스템 성능을 개선할 수 있습니다. 다만 데이터 쓰기부터 쿼리 가능한 상태가 되기까지의 지연 시간이 늘어납니다.

따라서 비즈니스의 지연 시간 요구 사항을 충족하는 범위에서 데이터 적재당 데이터양을 최대한 늘려 처리량을 높이고 시스템 오버헤드를 줄이세요.

테스트 데이터​

이 테스트는 Flink Connector의 배치 쓰기 모드를 사용하며, 종단 간 지연 시간과 데이터 적재 처리량에 초점을 맞춥니다. 배치 처리 간격은 Flink Connector 매개변수 sink.buffer-flush.interval로 제어합니다. Flink Connector 사용 방법은 Flink-Doris-Connector를 참조하세요.

머신 구성:

  • FE 1개: 8코어 CPU, 메모리 16 GB
  • BE 3개: 16코어 CPU, 메모리 64 GB

데이터 세트:

  • TPCH lineitem 데이터

배치 처리 간격과 동시성 수준에 따른 데이터 적재 성능:

배치 처리 간격(s)데이터 적재 동시성버킷 수처리량(행/s)종단 간 평균 지연 시간(s)종단 간 P99 지연 시간(s)
0.213260730.2110.517
1132315860.711.39
10132674375.6510.90
201329376910.96220.682
6013212500032.4662.17
0.2103293000.380.704
11032346330.751.47
101032820235.4410.43
20103213973111.1222.68
60103217164232.3761.93

버킷 수가 데이터 적재 성능에 미치는 영향:

배치 처리 간격(s)데이터 적재 동시성버킷 수처리량(행/s)종단 간 평균 지연 시간(s)종단 간 P99 지연 시간(s)
1104347220.862.28
11016345260.81.52
11032346330.751.47
11064348290.811.51
110128347220.831.55

Group Commit 테스트​

소규모 배치를 빈번하게 데이터 적재하는 경우 Group Commit을 활성화하는 것이 좋으며, 이를 통해 데이터 적재 성능을 크게 개선할 수 있습니다. Group Commit 성능 테스트 데이터는 Group Commit 성능을 참조하세요.

자주 묻는 질문​

Q1: 적절한 데이터 적재 방식을 어떻게 선택하나요?

데이터 소스와 실시간 요구 사항에 따라 선택하세요. 로컬 파일의 실시간 푸시에는 Stream Load, HDFS/S3의 대규모 배치에는 Broker Load, Kafka의 스트리밍 데이터에는 Routine Load, 외부 테이블 또는 Doris 테이블 간 ETL에는 Insert Into / Select, MySQL 호환 시나리오에는 MySQL Load를 사용하세요.

Q2: 빈번한 소규모 배치 데이터 적재가 성능에 큰 영향을 미치는 이유는 무엇인가요?

빈번한 소량 데이터 적재는 Doris에서 Compaction을 자주 수행하게 하여 심각한 쓰기 증폭을 일으킵니다. 클라이언트에서 수 MB~수 GB까지 데이터를 모으거나, Group Commit을 활성화하여 서버 측에서 배치 처리하세요.

Q3: 데이터 적재로 작은 파일이 많이 생성되어 Compaction 부담이 클 때는 어떻게 해야 하나요?

Group Commit을 활성화하여 소규모 트랜잭션을 병합하거나, 클라이언트에서 수백 MB~수 GB까지 데이터를 모은 후 데이터 적재를 수행하세요. 동시에 파티셔닝 및 버킷팅 설계를 검토하여 활성 Tablet이 너무 많아지지 않도록 하세요.

Q4: 단일 데이터 적재가 너무 많은 파티션을 포함하지 않아야 하는 이유는 무엇인가요?

각 Tablet은 메모리에 하나의 활성 Memtable을 유지합니다. 활성 Memtable이 사용하는 총 메모리가 너무 많으면 OOM을 방지하기 위해 조기 플러시가 발생하며, 이로 인해 작은 파일이 많이 생성되고 데이터 적재 성능이 저하됩니다. 단일 데이터 적재의 파티션 수를 제한하면 이 문제를 완화할 수 있습니다.

Q5: 데이터 적재당 데이터양은 클수록 좋은가요?

아닙니다. 각 배치를 100 GB 이하로 유지하세요. 배치가 지나치게 크면 재시도 비용과 BE 메모리 및 디스크에 미치는 영향이 커집니다. 대용량 로컬 파일에는 자동으로 배치 처리하는 streamloader 도구를 사용할 수 있습니다.

Q6: Tablet 크기로 1-10 GB를 권장하는 이유는 무엇인가요?

Tablet이 너무 작으면 집계 효과가 약해지고 메타데이터 관리 부담이 증가하며, 너무 크면 마이그레이션과 보충 비용이 커집니다. 1-10 GB는 경험적으로 데이터 적재, 쿼리, 복제본 관리 사이의 균형을 이루는 범위입니다.

Q7: Stream Load 동시성은 어떻게 설정해야 하나요?

단일 BE의 Stream Load 동시성은 128을 초과하지 않아야 하며(webserver_num_workers로 제한), 반드시 512 미만이어야 합니다(doris_max_remote_scanner_thread_pool_thread_num으로 제한). 그렇지 않으면 BE 프로세스가 응답하지 않을 수 있습니다.

Q8: MemTable 포워딩은 어떤 시나리오에서 적용되나요?

스토리지와 컴퓨팅이 통합된 배포 모드에서 INSERT INTO...SELECT에만 적용됩니다. 단일 복제본의 데이터 적재 시간은 기존의 36%로, 복제본 세 개의 경우 54%로 줄어듭니다. 컴퓨팅-스토리지 분리 모드는 현재 이 최적화를 지원하지 않습니다.

Q9: 데이터 편향을 어떻게 방지하나요?

적절한 버킷 수를 설정하고(압축 후 단일 Tablet 크기 1-10 GB) 적절한 버킷 키를 선택하세요. 랜덤 버킷팅 시나리오에서는 load_to_single_tablet=true를 활성화하여 데이터 분산 오버헤드를 줄일 수 있습니다.

문제 해결​

증상가능한 원인조사 및 해결 방법
낮은 데이터 적재 처리량, 빈번한 Compaction빈번한 소규모 배치 데이터 적재로 인한 쓰기 증폭클라이언트 측에서 배치 처리하거나 Group Commit 활성화
데이터 적재 중 작은 파일이 많이 생성됨단일 데이터 적재가 너무 많은 파티션을 포함하여 Memtable 조기 플러시 발생데이터 적재당 파티션 수를 줄이고 파티션을 순서대로 데이터 적재
데이터 적재 후 데이터가 쿼리 가능한 상태가 되기까지 오래 걸림쓰기를 완료한 복제본이 과반수에 도달하지 못함, 느린 PublishSHOW LOAD로 작업 상태를 확인하고, BE 상태를 점검하며, 필요하면 게시 시간 제한을 늘림
BE OOM 또는 빈번한 Flush동시에 활성화된 파티션/Tablet이 너무 많아 MemTable이 분산됨파티션을 순서대로 데이터 적재하고, 버킷 수를 줄이며, 동시성을 낮춤
FE Edit Log에 높은 부하 발생빈번한 소규모 배치 데이터 적재, 과도한 트랜잭션 수Group Commit을 활성화하거나 클라이언트 측에서 배치 처리하고, 동시성이 너무 높은지 검토
Compaction이 처리 속도를 따라가지 못하고 쿼리가 느려짐작은 파일이 너무 많음, 심각한 쓰기 증폭데이터 적재당 데이터양을 늘리고, 버킷팅을 튜닝하며, 필요하면 Compaction 매개변수를 조정
컴퓨팅-스토리지 분리 환경에서 데이터 적재 성능이 불안정함오브젝트 스토리지의 QPS 제한동시성을 제어하고, 배치당 데이터양을 늘리며, 오브젝트 스토리지 측의 QPS 할당량을 확인
데이터 적재에서 오류 행 보고데이터 형식 불일치, 컬럼 매핑 오류반환된 ErrorURL을 통해 오류 샘플을 확인하고 컬럼 매핑, 구분자 또는 오류 허용 범위를 조정
BE 프로세스가 응답하지 않음단일 BE의 Stream Load 동시성이 512를 초과함동시성을 낮추고 doris_max_remote_scanner_thread_pool_thread_num 조정
웹 서버 스레드 고갈, 느린 Stream Load단일 BE의 동시성이 128을 초과함동시성을 128 미만으로 유지하거나 webserver_num_workers 조정
낮은 Broker Load 동시성단일 압축 / Parquet / ORC 파일이 너무 크고 분할되지 않음데이터 적재 전에 큰 파일을 여러 개의 작은 파일로 분할
단일 Broker Load 실패 시 높은 재시도 비용배치 크기가 너무 큼각 배치를 100 GB 미만으로 유지하고 배치로 나누어 제출