Storage/Druid

druid 구조

Prower 2022. 7. 26. 00:40
728x90
반응형

# 이 글은 druid 공식문서의 design 파트를 정리한 글입니다. 

  • druid는 클라우드 서비스에 적용하기 쉬운 분산 구조로 이루어져 있다.
  • 이러한 구조 덕분에 몇가지 설정만으로 쉽고 유연하게 스케일 조절도 가능하며, 장애 복구 기능도 제공한다.

전체 구조

출처: https://druid.apache.org/docs/latest/design/architecture.html

드루이드 서비스

  • 드루이드는 다음의 서비스로 구성되어 있다.
  • coodinator service: 데이터 가용성을 책임지는 서비스
  • overlord service: 데이터 적재 작업을 제어
  • broker: 외부 클라이언트에서 들어온 쿼리문 제어
  • router service: request를 broker, coodinator, overlord에 분산
  • historical service: 쿼리가 가능한 데이터 저장
  • middlemanger service: 데이터를 적재 작업 담당

druid server

  • druid 서비스는 어떤 방식으로든 배포될 수 있지만, 운영상 유연함을 위해 다음의 3개 type의 서버로 나눠 배포하는 것을 추천한다.
  • master: coonidator, overlord 서비스 배포
  • query: broker, router 서비스 배포
  • data: historical, maddlemanger 서비스 배포

외부 의존성

  • 드루이드는 다음과 같은 외부 의존성을 갖는다.

deep storage

  • 시스템에 적재된 모든 데이터를 저장하는 모든 druid서버에서 접근 가능한 file storage
  • cluster 구조에서는 일반적으로 S3, HDFS 같은 분산 데이터 저장소나 mounted filesystem을 사용하여 구성한다.
  • 백업: druid process에서 데이터를 이동시킬 때 데이터를 백업하는 용도로도 사용한다.

metadata storage

  • 시스템에서 전반적으로 공유되는 metadata 저장하는 storage
  • cluster 구조에서는 일반적으로 RDBMS를 사용하여 구성한다.

zookeeper

  • internal service discovery, coordination에 사용

저장소의 구조

datasources and segments

  • druid의 데이터는 RDMS와 유사한 구조를 가진 datasource에 저장된다.
  • 각 datasource는 기본적으로 time에 대해 파티션 되어 있으며, 경우에 따라 다른 필드에 대해서도 파티셔닝이 된다.
  • 이렇게 파티션이된 시간 범위를 chunk라 한다.
  • chunk 내부에서도 데이터는 segment라고 하는 더 작은 단위로 나눠진다.

https://druid.apache.org/docs/latest/assets/druid-timeline.png

  • 정리하자면 위 그림과 같이 segment -> chunk로 구성되며 모두 시간 순서로 정리된다.

commit

  • 각 segment는 middlemanager에 의해 생성되며 mutable하고 uncommited 된 상태이다.
    • 즉, 변경이 가능한 데이터라는 의미
  • 주기적으로, segment 데이터는 commit되어 변경이 불가능한 상태로 deep storage에 저장된다.

indexing and handoff

  • indexing: segment가 생성되는 매커니즘
  • handoff: 생성된 segment가 publish 되고, 제공되는 매커니즘

indexing 과정

  1. indexing task가 실행되면, segment에 고유한 id값을 부여하고 segment를 생성한다.
    • task는 다음의 2종류가 있다.
    • appending task(데이터 추가): append 모드로 실행되어, overlord가 기존의 segment에 새로운 partition을 추가
    • overwriting task(데이터 수정): interval을 lock한 상태로, 새로운 버전의 segment를 새로 생성
  2. indexing task가 realtime으로 실행되면, 생성된 segment는 바로 query로 조회할 수 있다.
  3. indexing task가 segment로 부터 데이터를 읽는 과정을 끝낸 뒤, deep storage로 publish 한다.

segment identifiers

  • 모든 segment는 다음의 로 구성된 id값을 부여받는다.
  • datasource name
  • time interval
  • version number
  • partition number
  • 부여되는 id: {datasource name}{time interval}{version number}_{partition number}

segment versioning

  • version number는 데이터의 변경사항을 버저닝 하는데 사용한다.
  • 예를들어, 최초로 append 모드로 기록된 데이터면 1개의 version을 갖는다.
  • 만약, 데이터를 overwrite하면 druid는 예전 버전이 아닌 최신으로 기록된 버전을 조회하도록 query를 실행한다.
  • overwrite에 의해 새로 생성되는 segment는 같은 time interval, datasource를 갖지만 더 높은 버전의 version number를 부여받는다.
  • 그리고 old 버전으로 기록된 segment는 차후에 cluster에 의해 제거된다.

availability and consistency

  • druid는 데이터 적재와 쿼리가 나눠져 있는 구조이다.

데이터 적재

  • druid는 transaction을 통해 데이터가 all-or-nothing 으로 적재되는 것을 보장한다.
  • 적재 method
    • druid는 데이터를 적재하는데 다음과 같은 method를 사용한다.
    • steaming 적재(kafka, kinesis): segment 단위 스트리밍 방식으로 데이터를 적재. 만약 데이터가 publish 되지 않은 상태에서 적재가 실패할 경우 rollback 가능
    • hadoop 기반의 batch 적재: 하나의 task 마다 모든 segment를 single transaction으로 publish
    • native batch ingestion: 병렬 모드에서, subtask가 끝난 뒤에 모든 segment 데이터를 single transacion으로 publish

쿼리

  • 쿼리가 들어오면 druid broker가 적절한 segment version을 선정하여 segment를 결과에 포함시킨다.
728x90
반응형