Apache Doris 의 워크로드 격리 기능에 대한 심층적인 소개입니다. 하지만 먼저 워크로드 격리가 필요한 이유와 시기는 무엇입니까? 다음 상황 중 하나와 관련이 있는 경우 계속 읽으면 해결책이 나올 것입니다.
동일한 클러스터를 공유하는 다양한 비즈니스 부서 또는 테넌트가 있고 워크로드 간섭을 방지하려고 합니다.
다양한 우선순위 수준의 쿼리 작업이 있고 리소스 및 실행 측면에서 중요한 작업(예: 실시간 데이터 분석 및 온라인 트랜잭션)에 우선순위를 부여하려고 합니다.
워크로드 격리가 필요하지만 높은 비용 효율성과 리소스 활용률도 필요합니다.
Apache Doris는 리소스 태그 및 워크로드 그룹을 기반으로 워크로드 격리를 지원합니다. 리소스 태그는 백엔드 노드 수준에서 다양한 워크로드에 대한 CPU 및 메모리 리소스를 격리하는 반면, 워크로드 그룹 메커니즘은 더 높은 리소스 활용도를 위해 백엔드 노드 내의 리소스를 추가로 나눌 수 있습니다.
Apache Doris의 아키텍처부터 시작해 보겠습니다. Doris에는 프런트엔드(FE)와 백엔드(BE)라는 두 가지 유형의 노드가 있습니다. FE 노드는 메타데이터를 저장하고, 클러스터를 관리하고, 사용자 요청을 처리하고, 쿼리 계획을 구문 분석하는 반면, BE 노드는 계산 및 데이터 저장을 담당합니다. 따라서 BE 노드는 주요 리소스 소비자입니다.
리소스 태그 기반 격리 솔루션의 주요 아이디어는 동일한 태그의 BE 노드가 리소스 그룹을 구성하는 클러스터의 BE 노드에 태그를 할당하여 컴퓨팅 리소스를 그룹으로 나누는 것입니다. 리소스 그룹은 데이터 저장 및 계산 단위로 간주될 수 있습니다. Doris에 수집된 데이터의 경우 시스템은 구성에 따라 데이터 복제본을 다른 리소스 그룹에 기록합니다. 쿼리는 실행을 위해 해당 리소스 그룹 에도 할당됩니다.
예를 들어 3-BE 클러스터에서 읽기 및 쓰기 작업 부하를 분리하려면 다음 단계를 수행하면 됩니다.
BE 노드에 리소스 태그 할당 : 2개의 BE를 "읽기" 태그에 바인딩하고 1개의 BE를 "쓰기" 태그에 바인딩합니다.
데이터 복제본에 리소스 태그 할당 : 표 1에 3개의 복제본이 있다고 가정하고 그 중 2개를 "읽기" 태그에 바인딩하고 1개를 "쓰기" 태그에 바인딩합니다. 복제본 3에 기록된 데이터는 복제본 1 및 복제본 2와 동기화되며, 데이터 동기화 프로세스는 BE 1 및 BE2의 리소스를 거의 사용하지 않습니다.
리소스 태그에 작업 그룹 할당 : SQL에 "읽기" 태그가 포함된 쿼리는 "읽기" 태그가 지정된 노드(이 경우 BE 1 및 BE 2)로 자동 라우팅됩니다. 데이터 쓰기 작업의 경우 해당 노드(BE 3)로 라우팅될 수 있도록 "쓰기" 태그를 할당해야 합니다. 이러한 방식으로 복제본 3에서 복제본 1과 2로의 데이터 동기화 오버헤드를 제외하고 읽기 및 쓰기 워크로드 간에 리소스 경합이 발생하지 않습니다.
또한 리소스 태그는 Apache Doris에서 다중 테넌트를 활성화합니다. 예를 들어 "사용자 A"로 태그가 지정된 컴퓨팅 및 스토리지 리소스는 사용자 A 전용이고 "사용자 B"로 태그가 지정된 리소스는 사용자 B에게만 적용됩니다. 이것이 Doris가 BE 측에서 리소스 태그를 사용하여 다중 테넌트 리소스 격리를 구현하는 방법입니다. .
BE 노드를 그룹으로 나누면 높은 수준의 격리 가 보장됩니다.
서로 다른 테넌트의 CPU, 메모리 및 I/O는 물리적으로 격리됩니다.
한 테넌트는 다른 테넌트의 오류(예: 프로세스 충돌)로 인해 영향을 받지 않습니다.
그러나 몇 가지 단점이 있습니다.
읽기-쓰기 분리에서는 데이터 쓰기가 중지되면 "쓰기" 태그가 지정된 BE 노드가 유휴 상태가 됩니다. 이렇게 하면 전체 클러스터 활용도가 줄어듭니다.
멀티 테넌시에서 각각에 별도의 BE 노드를 할당하여 동일한 테넌트의 다양한 워크로드를 더욱 격리하려는 경우 상당한 비용과 낮은 리소스 활용도를 견뎌야 합니다.
테넌트 수는 데이터 복제본 수와 연결됩니다. 따라서 5개의 테넌트가 있는 경우 5개의 데이터 복제본이 필요합니다. 엄청난 저장 공간이군요.
이를 개선하기 위해 Apache Doris 2.0.0에서는 Workload Group 기반의 워크로드 격리 솔루션을 제공하고 Apache Doris 2.1.0 에서는 이를 강화했습니다 .
워크로드 그룹 기반 솔루션은 보다 세분화된 리소스 분할을 실현합니다. 이는 BE 노드의 프로세스 내에서 CPU와 메모리 리소스를 추가로 나눕니다. 즉, 한 BE 노드의 쿼리가 어느 정도 서로 격리될 수 있음을 의미합니다. 이는 BE 프로세스 내에서 리소스 경쟁을 방지하고 리소스 활용도를 최적화합니다.
사용자는 쿼리를 작업 그룹에 연결하여 쿼리에서 사용할 수 있는 CPU 및 메모리 리소스의 비율을 제한할 수 있습니다. 클러스터 부하가 높을 때 Doris는 작업 그룹에서 리소스를 가장 많이 소모하는 쿼리를 자동으로 종료할 수 있습니다. 클러스터 부하가 낮을 때 Doris는 여러 작업 그룹이 유휴 리소스를 공유하도록 허용할 수 있습니다.
Doris는 CPU 소프트 제한과 CPU 하드 제한을 모두 지원합니다. 소프트 제한을 사용하면 워크로드 그룹이 제한을 초과하고 유휴 리소스를 활용하여 보다 효율적으로 활용할 수 있습니다. 하드 제한은 워크로드 그룹의 상호 영향을 방지하므로 안정적인 성능을 확실하게 보장합니다.
(CPU 소프트 제한과 CPU 하드 제한은 서로 모순됩니다. 사용 사례에 따라 둘 중 하나를 선택할 수 있습니다.)
리소스 태그 기반 솔루션과의 차이점은 다음과 같습니다.
워크로드 그룹은 프로세스 내에 형성됩니다. 여러 작업 로드 그룹이 동일한 BE 노드 내의 리소스를 놓고 경쟁합니다.
워크로드 그룹은 리소스 관리 방법일 뿐이므로 데이터 복제본 배포에 대한 고려는 불가능합니다.
CPU 소프트 제한은 개념적으로 가중치와 유사한 cpu_share
매개변수에 의해 구현됩니다. cpu_share
가 더 높은 워크로드 그룹에는 시간 슬롯 동안 더 많은 CPU 시간이 할당됩니다.
예를 들어 그룹 A의 cpu_share
는 1이고 그룹 B는 9로 구성된 경우 10초의 시간 슬롯에서 그룹 A와 그룹 B가 모두 완전히 로드되면 그룹 A와 그룹 B는 1초를 소비할 수 있으며 CPU 시간은 각각 9초입니다.
실제 사례에서는 클러스터의 모든 워크로드가 전체 용량으로 실행되지는 않습니다. 소프트 제한에 따라 그룹 B의 워크로드가 낮거나 0인 경우 그룹 A는 10초의 CPU 시간을 모두 사용할 수 있으므로 클러스터의 전체 CPU 사용률이 늘어납니다.
소프트 제한은 유연성과 더 높은 리소스 활용률을 제공합니다. 반대로 성능 변동이 발생할 수 있습니다.
Apache Doris 2.1.0의 CPU 하드 제한은 안정적인 성능이 필요한 사용자를 위해 설계되었습니다. 간단히 말해서 CPU 하드 제한은 유휴 CPU 리소스가 있는지 여부에 관계없이 워크로드 그룹이 해당 제한보다 더 많은 CPU 리소스를 사용할 수 없음을 정의합니다.
작동 방식은 다음과 같습니다.
그룹 A가 cpu_hard_limit=10%
로 설정되고 그룹 B가 cpu_hard_limit=90%
로 설정되었다고 가정합니다. 그룹 A와 그룹 B가 모두 전체 로드에서 실행되는 경우 그룹 A와 그룹 B는 각각 전체 CPU 시간의 10%와 90%를 사용합니다. 차이점은 그룹 B의 작업량이 감소하는 경우입니다. 이러한 경우 그룹 A의 쿼리 부하가 아무리 높더라도 할당된 CPU 리소스를 10% 이상 사용해서는 안 됩니다.
소프트 제한과 달리 하드 제한은 유연성을 희생하고 리소스 활용률을 높일 수 있는 대신 안정적인 시스템 성능을 보장합니다.
BE 노드의 메모리는 다음 부분으로 구성됩니다.
운영 체제용으로 예약된 메모리입니다.
쿼리가 아닌 쿼리에 의해 소비되는 메모리. 이는 작업 그룹의 메모리 통계에서 고려되지 않습니다.
데이터 쓰기를 포함한 쿼리에 의해 메모리가 소비됩니다. 이는 워크로드 그룹에서 추적하고 제어할 수 있습니다.
memory_limit
매개변수는 BE 프로세스 내의 작업 그룹에 사용할 수 있는 최대 메모리(%)를 정의합니다. 또한 리소스 그룹의 우선순위에도 영향을 미칩니다.
초기 상태에서는 우선 순위가 높은 리소스 그룹에 더 많은 메모리가 할당됩니다. enable_memory_overcommit
설정하면 유휴 공간이 있을 때 리소스 그룹이 제한보다 더 많은 메모리를 차지하도록 허용할 수 있습니다. 메모리가 부족하면 Doris는 작업을 취소하여 커밋된 메모리 리소스를 회수합니다. 이 경우 시스템은 우선 순위가 높은 리소스 그룹에 대해 가능한 한 많은 메모리 리소스를 유지합니다.
클러스터가 처리할 수 있는 것보다 더 많은 로드를 처리하는 경우가 있습니다. 이 경우 새 쿼리 요청을 제출하는 것은 효과가 없을 뿐만 아니라 진행 중인 쿼리에도 방해가 됩니다.
이를 개선하기 위해 Apache Doris는 쿼리 대기열 메커니즘을 제공합니다. 사용자는 클러스터에서 동시에 실행할 수 있는 쿼리 수에 제한을 둘 수 있습니다. 쿼리 대기열이 가득 차거나 대기 시간이 초과되면 쿼리가 거부되므로 높은 부하에서도 시스템 안정성이 보장됩니다.
쿼리 큐 메커니즘에는 max_concurrency
, max_queue_size
및 queue_timeout
의 세 가지 매개변수가 포함됩니다.
CPU 소프트 제한과 하드 제한의 효율성을 입증하기 위해 몇 가지 테스트를 수행했습니다.
환경: 단일 머신, 16코어, 64GB
배포: FE 1개 + BE 1개
데이터세트: ClickBench, TPC-H
부하 테스트 도구: Apache JMeter
두 클라이언트를 시작하고 각각 워크로드 그룹을 사용하거나 사용하지 않고 지속적으로 쿼리를 제출합니다(ClickBench Q23). 테스트 결과에 영향을 미치지 않도록 하려면 페이지 캐시를 비활성화해야 합니다.
두 테스트에서 두 클라이언트의 처리량을 비교하면 다음과 같은 결론을 내릴 수 있습니다.
워크로드 그룹을 구성하지 않으면 두 클라이언트가 CPU 리소스를 동일하게 소비합니다.
워크로드 그룹을 구성 하고 cpu_share
2:1로 설정하면 두 클라이언트의 처리량 비율은 2:1입니다. cpu_share
가 높을수록 클라이언트 1에는 더 많은 CPU 리소스가 제공되며 더 높은 처리량을 제공합니다.
클라이언트를 시작하고 워크로드 그룹에 대해 cpu_hard_limit=50%
설정한 후 동시성 수준 1, 2, 4에서 각각 ClickBench Q23을 5분 동안 실행합니다.
쿼리 동시성이 증가함에 따라 CPU 사용률은 약 800%로 유지됩니다. 이는 8개의 코어가 사용된다는 의미입니다. 16코어 시스템에서는 예상대로 50%의 활용률을 보입니다. 또한 CPU 하드 제한이 적용되므로 동시성이 증가함에 따라 TP99 대기 시간이 증가하는 것도 예상되는 결과입니다.
실제 사용에서 사용자는 쿼리 처리량보다는 쿼리 대기 시간에 특히 관심을 가집니다. 대기 시간은 사용자 환경에서 더 쉽게 인식할 수 있기 때문입니다. 이것이 바로 우리가 시뮬레이션된 프로덕션 환경에서 워크로드 그룹의 효율성을 검증하기로 결정한 이유입니다.
단일 테이블 집계 및 조인 쿼리를 포함하여 1초 이내에 완료되어야 하는 쿼리(ClickBench Q15, Q17, Q23 및 TPC-H Q3, Q7, Q19)로 구성된 SQL 세트를 선택했습니다. TPC-H 데이터 세트의 크기는 100GB입니다.
마찬가지로 워크로드 그룹을 구성하거나 구성하지 않고 테스트를 수행합니다.
결과는 다음과 같습니다.
워크로드 그룹 없음 (테스트 1 및 2 비교): 클라이언트 2의 동시성을 다이얼링할 때 두 클라이언트 모두 쿼리 대기 시간이 2~3배 증가하는 것을 경험했습니다.
워크로드 그룹 구성 (테스트 3 및 4 비교): 클라이언트 2의 동시성이 증가함에 따라 클라이언트 1의 성능 변동이 훨씬 작아졌습니다. 이는 워크로드 격리를 통해 효과적으로 보호되고 있음을 입증합니다.
리소스 태그 기반 솔루션은 철저한 워크로드 격리 계획입니다. Workload Group 기반 솔루션은 리소스 격리와 활용 사이의 더 나은 균형을 실현하고 안정성 보장을 위해 쿼리 대기열 메커니즘으로 보완됩니다.
그렇다면 사용 사례에 맞게 어떤 것을 선택해야 할까요? 우리의 권장 사항은 다음과 같습니다.
리소스 태그 : 부서의 다양한 비즈니스 라인이 동일한 클러스터를 공유하는 사용 사례에 사용되므로 리소스와 데이터가 서로 다른 테넌트에 대해 물리적으로 격리됩니다.
Workload Group : 유연한 리소스 할당을 위해 하나의 클러스터가 다양한 쿼리 워크로드를 수행하는 사용 사례입니다.
향후 릴리스에서는 워크로드 그룹 및 쿼리 대기열 기능의 사용자 경험을 계속해서 개선할 예정입니다.
쿼리를 취소하여 메모리 공간을 확보하는 것은 잔인한 방법입니다. 이를 디스크 스필링(Disk Spilling) 방식으로 구현해 쿼리 성능의 안정성을 높일 예정입니다.
BE의 쿼리가 아닌 데 사용된 메모리는 작업 부하 그룹의 메모리 통계에 포함되지 않으므로 사용자는 BE 프로세스 메모리 사용량과 작업 부하 그룹 메모리 사용량 간의 차이를 관찰할 수 있습니다. 혼란을 피하기 위해 이 문제를 다루겠습니다.
쿼리 대기열 메커니즘에서 클러스터 로드는 최대 쿼리 동시성을 설정하여 제어됩니다. BE의 리소스 가용성을 기반으로 동적 최대 쿼리 동시성을 활성화할 계획입니다. 이는 클라이언트 측에 역압을 발생시켜 클라이언트가 계속해서 높은 로드를 제출할 때 Doris의 가용성을 향상시킵니다.
리소스 태그의 주요 아이디어는 BE 노드를 그룹화하는 것이고, 워크로드 그룹의 주요 아이디어는 단일 BE 노드의 리소스를 추가로 나누는 것입니다. 이러한 아이디어를 이해하려면 사용자는 먼저 Doris의 BE 노드 개념을 배워야 합니다. 그러나 운영 관점에서 사용자는 각 워크로드의 리소스 소비 비율과 클러스터 로드가 포화되었을 때 어떤 우선 순위를 가져야 하는지만 이해하면 됩니다. 따라서 우리는 블랙박스에 BE 노드의 개념을 유지하는 등 사용자를 위한 학습 곡선을 평탄화할 수 있는 방법을 모색할 것입니다.
Apache Doris의 워크로드 격리에 대한 추가 지원을 받으려면 Apache Doris 커뮤니티에 가입하세요.