<@U0A71G31CDV> starrocks v4.1.1 기준의 FE + CN (shar...
# questions-and-troubleshooting
u
@Rocky starrocks v4.1.1 기준의 FE + CN (shard data) - iceberg (S3 저장) 구조로 k8s 환경에서 활용 중에 insert 쿼리 실행 시 CN 의 cpu 부하가 발생해서 cpu 설정을 늘려줬으나 늘려준 만금 계속 cpu를 점유하는 문제가 발생하고 cpu 증가 이후 Memory of default_wg exceed limit … Mem usage has exceed the limit of query pool …errror가 발생하고 있는 상황에 대응방법은?
r
StarRocks v4.1.1 환경에서 FE + CN(Shared Data) 구조로 Iceberg(S3)에
INSERT
작업을 수행할 때 발생하는 CPU 부하 및 메모리 초과 에러(
Memory of default_wg exceed limit
,
query pool exceed limit
)는 주로 높은 병렬도(Parallelism)에 따른 리소스 경합 때문입니다. CPU 설정을 늘렸음에도 계속 점유율이 높은 것은 StarRocks의 Pipeline Engine이 늘어난 CPU 코어 수에 맞춰 병렬도(
pipeline_dop
)를 자동으로 높였기 때문이며, 이로 인해 각 병렬 태스크가 사용하는 메모리 버퍼가 합산되어 메모리 임계치를 넘어선 것으로 분석됩니다. 다음은 이 상황에 대한 단계별 대응 방법입니다. 1. 쿼리 병렬도 제한 (
pipeline_dop
)
CPU를 늘렸을 때 메모리 에러가 발생했다면, 현재
INSERT
쿼리의 병렬도가 너무 높게 설정되어 있을 가능성이 큽니다. 병렬도가 높을수록 S3로 데이터를 쓰기 위한 인코딩/압축 버퍼 메모리 사용량이 급증합니다. * 조치: 해당 세션에서 병렬도를 수동으로 낮추어 메모리 사용량을 조절합니다.
Copy code
sql
    -- 현재 CPU 코어 수보다 낮은 값(예: 8 또는 16)으로 설정하여 테스트
    SET pipeline_dop = 8;
    INSERT INTO iceberg_table SELECT ...;
2. 리소스 그룹(Resource Group) 설정 확인 및 조정
Memory of default_wg exceed limit
에러는
default_wg
그룹에 할당된 메모리 쿼터가 부족하다는 의미입니다. v4.x에서는 기본적으로 모든 쿼리가 `default_wg`를 사용합니다. * 확인:
SHOW RESOURCE GROUPS;
명령어로 `default_wg`의
mem_limit
설정을 확인합니다. * 조치: 만약 특정 서비스나 쿼리가 메모리를 독점하는 것을 막고 싶다면,
INSERT
전용 리소스 그룹을 생성하거나 `default_wg`를 조정할 수 있습니다. (다만, `default_wg`는 보통 100%로 설정되어 있으므로 아래 3번 항목의 전체 쿼리 풀 설정을 먼저 확인해야 합니다.) 3. 쿼리 풀(Query Pool) 및 세션 메모리 제한 확대 `Mem usage has exceed the limit of query pool`은 CN 노드에서 쿼리 실행에 할당된 전체 메모리 영역이 가득 찼음을 의미합니다. * 세션 변수 조정: 개별
INSERT
쿼리가 사용할 수 있는 메모리 상한을 높여줍니다.
Copy code
sql
    SET exec_mem_limit = 17179869184; -- 16GB (필요에 따라 조절)
    -- 또는 v4.x 권장 변수
    SET query_mem_limit = 17179869184;
* CN 설정 확인 (cn.conf): CN 노드 자체의 `mem_limit`가 k8s Pod Resource Limit과 적절히 매칭되어 있는지 확인합니다. 보통 Pod Limit의 90% 정도로 설정합니다. 4. Iceberg Sink 관련 메모리 최적화 Iceberg로 데이터를 쓸 때 S3로 전송하기 전 데이터를 버퍼링하고 Parquet 등으로 인코딩하는 과정에서 메모리가 많이 소모됩니다. * 버퍼 사이즈 조정:
insert_max_buffer_size
등의 변수를 통해 싱크 시 사용되는 버퍼 크기를 조절할 수 있습니다. (v4.1 기준 최적화 옵션 확인 필요) * 데이터 셔플링 감소:
INSERT INTO ... SELECT
시 `ORDER BY`나 복잡한 조인이 포함되어 있다면, 이를 별도의 CTAS나 임시 테이블을 통해 단계를 나누어 실행하는 것이 메모리 관리에 유리합니다. 5. k8s 환경 특이사항 * Memory Fragmentation: StarRocks는 `jemalloc`을 사용합니다. v4.1에서는 대형 메모리 할당 방식이 변경되었으므로, CN의 `cn.conf`에서 `mem_limit`가 실제 k8s 컨테이너의 제한보다 너무 높게 설정되어 있지 않은지 확인하십시오. (StarRocks가 인식하는 메모리가 k8s Limit보다 크면 Pod가 강제 종료(OOM Kill)될 수 있으나, 위 에러는 StarRocks가 스스로 제어하는 내부 에러이므로 설정을 늘려주는 것이 맞습니다.) 요약하자면: 1. CPU를 늘린 만큼 *`pipeline_dop`가 과하게 높아지지 않도록 세션 레벨에서 제한*하십시오. 2. `query_mem_limit`를 늘려 개별 쿼리가 확보할 수 있는 메모리 폭을 넓히십시오. 3. CN 노드의
cn.conf
내
load_process_max_memory_limit_percent
(기본 30%) 설정을 확인하여
INSERT
작업에 할당된 메모리 비율이 너무 낮지는 않은지 확인하십시오. 더 자세한 진단이 필요하다면 에러 발생 시점의
SHOW PROFILE FOR QUERY <query_id>;
결과에서 어떤 Operator(특히
IcebergTableSink
또는
Scan
)가 메모리를 과다 점유하는지 확인하는 것이 가장 정확합니다. References • data_source/catalog/iceberg/iceberg_catalog.md • loading/loading_introduction/loading_considerations.md • loading/Flink-connector-starrocks.md
u
@Rocky pipeline_dop 에 대해 자세히 설명해줘
r
*`pipeline_dop`*(Degree of Parallelism)는 StarRocks의 *Pipeline 실행 엔진이 쿼리를 병렬로 처리하는 단위(수치)*를 의미합니다. 사용자께서 CPU를 늘렸음에도 CPU 부하가 여전하고 메모리 초과가 발생하는 원인의 핵심이 바로 이 설정에 있습니다. 자세한 내용은 다음과 같습니다. 1. 주요 역할 및 작동 방식 * 병렬 처리 제어: 하나의 쿼리 실행 계획(Fragment)을 여러 개의 작은 실행 단위(Driver)로 쪼개어 여러 CPU 코어에서 동시에 실행하게 합니다. * 자동 설정 (
0
default):
기본값이 `0`인 경우, StarRocks는 시스템의 *CPU 코어 수의 절반*을 기준으로 병렬도를 자동 계산합니다. _ _예: CN 노드의 CPU가 32코어라면, `pipeline_dop`은 자동으로 16으로 설정됩니다.* * 문제의 원인: k8s에서 CN의 CPU 할당량(Limit)을 늘리면, StarRocks는 이를 감지하고 `pipeline_dop`을 자동으로 더 높게 잡습니다. 결과적으로 더 많은 CPU를 사용하려 들고, 각 병렬 태스크(Driver)가 사용하는 메모리 버퍼가 합산되어 전체 메모리 임계치를 넘게 되는 것입니다. 2. CPU와 메모리에 미치는 영향 * CPU:
pipeline_dop
수치가 높을수록 더 많은 스레드가 동시에 작업을 수행하므로 CPU 사용률이 올라가고 쿼리 속도는 빨라질 수 있습니다. * 메모리: 중요하게 보셔야 할 부분입니다. Iceberg와 같은 외부에 데이터를 쓰는
INSERT
작업 시, 각 병렬 프로세스는 데이터를 S3로 보내기 전 인코딩(Parquet/Orc) 및 버퍼링을 위해 *독립적인 메모리 공간*을 사용합니다. *
전체 메모리 사용량 ≈ (pipeline_dop) × (연산당 메모리 버퍼)
* 따라서 CPU를 늘려 `pipeline_dop`이 커지면 메모리 사용량도 그에 비례해 선형적으로 증가하며, 결국 `default_wg`나 `query pool`의 한도를 초과하게 됩니다. 3. Iceberg 쓰기 관련 특수 변수:
pipeline_sink_dop
v3.x 이후 버전부터는 일반 연산과 별개로 *Iceberg/Hive 등의 외부 테이블에 데이터를 쓸 때(Sink)의 병렬도*를 조절하는 변수가 추가되었습니다. *
pipeline_sink_dop
: 외부 카탈로그에 데이터를 쓸 때의 병렬도입니다. 이 값도 기본값은 `0`이며 시스템에 의해 자동 조절됩니다.
INSERT
부하를 줄이려면 이 값을 명시적으로 낮추는 것이 효과적일 수 있습니다. 4. 권장 대응 전략 현재 상황에서는 무조건적인 자원 증설보다는 *병렬도를 수동으로 제한*하여 자원 사용의 "상한선"을 정해주는 것이 필요합니다. 1. 세션 레벨에서 병렬도 제한 테스트:
Copy code
sql
    -- CPU를 충분히 쓰되 메모리 폭주를 막기 위해 수동으로 고정 (예: 8 혹은 16)
    SET pipeline_dop = 8;
    SET pipeline_sink_dop = 8; -- Iceberg 쓰기 병렬도 직접 제한
    INSERT INTO iceberg_table SELECT ...;
2. 최대 병렬도 상한 설정: 시스템 전체적으로 너무 높은 병렬도가 할당되는 것을 막으려면 FE 설정이나 세션 변수에서 `max_pipeline_dop`을 조정할 수 있습니다. 3. 메모리 제한 증가 (병렬도를 낮추고 싶지 않을 경우): 늘려준 CPU만큼의 성능을 다 쓰고 싶다면, 에러 메시지에 나온 `query_mem_limit`를 더 크게 설정해야 합니다. 하지만 이는 k8s Pod의 실제 메모리 물리적 한계(Limit) 내에서만 유효합니다. 결론적으로, CPU를 늘린 만큼 StarRocks가 "더 세게" 일을 하려고 병렬도를 높였고, 그 과정에서 메모리 사용량이 감당 범위를 벗어난 상태입니다. *`pipeline_dop`과 `pipeline_sink_dop`을 현재 CPU 코어 수보다 낮게 명시적으로 설정*하여 메모리 점유율을 안정화시킨 후 조금씩 높여가며 최적의 지점을 찾으시는 것을 권장합니다. References • sql-reference/System_variable.md • knowledge/usage/best-practice.md • administration/management/resource_group.md References • sql-reference/System_variable.md • knowledge/usage/best-practice.md • faq/Sql_faq.md