목차
- 1. 왜 OpenStack Nova 성능 최적화가 생각보다 까다로운가
- 2. Nova CPU 스케줄링 개념, 쉽게 말해 이런 구조입니다
- 2-1. Shared CPU와 Dedicated CPU 차이
- 2-2. 리소스 할당에서 꼭 같이 봐야 할 요소
- 3. 실전 기준선 만들기: benchmark 전에 먼저 해야 할 것
- 4. Nova CPU 스케줄링 설정 확인 포인트
- 5. 리소스 할당 전략: 워크로드별로 다르게 가져가야 합니다
- 5-1. 일반 웹/배치 워크로드
- 5-2. DB, 메시지 큐, 지연 민감 서비스
- 5-3. 혼합 클러스터 운영 팁
- 6. ⚠️ 실제로 자주 겪는 트러블슈팅
- 6-1. Pinning은 했는데 성능이 기대보다 안 나오는 경우
- 6-2. 동일한 벤치마크인데 결과 편차가 큰 경우
- 6-3. 호스트는 여유 있는데 스케줄링이 실패하는 경우
- 6-4. 에뮬레이터 스레드가 의외의 병목이 되는 경우
- 7. 검증은 이렇게 합니다: 가상 머신 성능 확인 절차
- 8. 정리와 다음 단계: 무엇부터 손대면 좋을까
- 자주 묻는 질문
- Q1. CPU overcommit을 무조건 낮추면 성능이 좋아지나요?
- Q2. Nova CPU 스케줄링만 조정하면 끝인가요?
- Q3. benchmark 결과가 매번 다르면 무엇부터 확인해야 하나요?
[OpenStack] OpenStack Nova 성능 최적화: CPU 스케줄링 및 리소스 할당 분석
OpenStack Nova 성능 최적화 이야기는 결국 운영하면서 한 번쯤 꼭 부딪히는 문제로 이어집니다. 가상 머신은 충분히 띄웠는데, 어떤 인스턴스는 반응이 빠르고 어떤 인스턴스는 같은 flavor(플레이버, 가상 머신 자원 정의)인데도 체감 성능이 들쭉날쭉하거든요. 저도 처음엔 "스토리지가 느린가?" 하고 엉뚱한 데를 먼저 봤었는데, 실제로 파고 들어가 보니 Nova CPU 스케줄링과 리소스 할당 방식이 병목의 핵심인 경우가 많았습니다. 특히 benchmark(벤치마크, 성능 측정) 결과를 비교할 때 CPU 오버커밋(overcommit, 실제 물리 자원보다 더 많이 논리 할당)과 NUMA(Non-Uniform Memory Access, 메모리 접근 거리가 다른 구조) 인식 여부가 결과를 꽤 크게 흔들더라고요.
이번 글에서는 제가 홈랩과 테스트 환경에서 반복적으로 확인했던 관찰 포인트를 기준으로, OpenStack Nova 성능 최적화를 어디서부터 봐야 하는지 정리해보겠습니다. 숫자를 지어내거나 과장된 벤치마크를 보여드리기보다는, 무엇을 설정하고 무엇을 검증해야 재현 가능한 성능 분석이 되는지에 초점을 맞추겠습니다.
Nova 스케줄러와 컴퓨트 노드, 하이퍼바이저, NUMA 토폴로지 관계를 한눈에 보여주는 개요 이미지입니다.
1. 왜 OpenStack Nova 성능 최적화가 생각보다 까다로운가
쉽게 말해 Nova는 "가상 머신을 어디에 올릴지"만 결정하는 도구가 아닙니다. CPU pinning(피닝, vCPU를 특정 pCPU에 고정), emulator thread(에뮬레이터 스레드), huge page(휴즈페이지, 큰 메모리 페이지), NUMA topology(토폴로지, 자원 배치 구조) 같은 요소가 다 엮여 있습니다. 그래서 표면적으로는 인스턴스 생성이 잘 되더라도, 실제 가상 머신 성능은 스케줄링 정책에 따라 크게 달라질 수 있습니다.
제가 직접 해보니 가장 흔한 착각은 이겁니다. "vCPU 개수만 맞으면 성능도 비슷하겠지"라는 생각이요. 근데 현실은 그렇지 않더라고요. 같은 4 vCPU 인스턴스라도 어느 소켓(socket, CPU 패키지) 위에 배치됐는지, 이웃한 워크로드가 얼마나 시끄러운지(noisy neighbor, 자원 경쟁을 유발하는 인접 워크로드), CPU 공유 정책이 어떤지에 따라 결과가 달라집니다.
- CPU overcommit ratio가 높으면 밀도는 올라가지만 지연 시간이 튈 수 있습니다.
- Dedicated CPU policy를 쓰면 예측 가능성은 좋아지지만 수용량은 줄어듭니다.
- NUMA mismatch가 나면 메모리 접근 비용이 늘어나 체감 성능이 떨어질 수 있습니다.
- Benchmark 결과는 테스트 시간대와 이웃 인스턴스 상태에 따라서도 흔들립니다.
2. Nova CPU 스케줄링 개념, 쉽게 말해 이런 구조입니다
여기서 중요한 포인트! Nova CPU 스케줄링은 단순한 라운드로빈(round-robin, 순환 배치)이 아닙니다. 스케줄러는 호스트 필터(filter, 후보 선별 규칙)와 weighers(가중치 계산기)를 사용해서 컴퓨트 노드를 고릅니다. 그 다음 실제 하이퍼바이저 계층에서 vCPU와 pCPU 관계가 정해지죠.
2-1. Shared CPU와 Dedicated CPU 차이
| 구분 | 설명 | 장점 | 주의점 |
|---|---|---|---|
| Shared CPU | 여러 VM이 물리 CPU 시간을 공유 | 집적도 높음 | 성능 편차 가능 |
| Dedicated CPU | 특정 pCPU를 인스턴스에 고정 할당 | 예측 가능한 성능 | 운영 유연성 감소 |
| CPU Pinning | vCPU를 지정 코어에 매핑 | 지터 감소 | NUMA 설계 필요 |
실제로 써보니까 데이터베이스나 NFV(Network Functions Virtualization, 네트워크 기능 가상화)처럼 지연 시간에 민감한 워크로드는 Shared CPU보다 Dedicated CPU 쪽이 훨씬 해석하기 편했습니다. 반대로 일반 웹 애플리케이션은 적당한 오버커밋이 더 경제적일 때가 많았고요.
2-2. 리소스 할당에서 꼭 같이 봐야 할 요소
- vCPU allocation ratio: 논리적으로 얼마나 더 많이 잡을지
- RAM allocation ratio: 메모리 과할당 정책
- Reserved host memory: 호스트 OS와 에이전트가 쓸 여유 공간
- NUMA affinity: CPU와 메모리 지역성 유지
- Huge pages: TLB 부담 감소에 유리
저도 처음엔 헷갈렸는데, CPU만 최적화하면 끝이 아니더라고요. 메모리 배치가 틀어지면 CPU pinning을 해도 기대만큼 안 나오는 경우가 있습니다.
3. 실전 기준선 만들기: benchmark 전에 먼저 해야 할 것
OpenStack Nova 성능 최적화를 하겠다고 바로 설정부터 바꾸면 나중에 비교가 안 됩니다. 삽질 좀 했습니다 ㅎㅎ 결국 가장 먼저 해야 하는 건 기준선(baseline, 비교 기준)을 만드는 일입니다.
- 테스트 대상 flavor를 고정합니다.
- 테스트용 이미지와 커널 상태를 동일하게 맞춥니다.
- 동일한 시간대에 반복 실행합니다.
- 가능하면 noisy neighbor 영향을 줄인 별도 호스트를 씁니다.
- 인스턴스 내부 지표와 호스트 지표를 같이 수집합니다.
제가 권장하는 최소 수집 항목은 아래 정도입니다.
# Compute node
lscpu
numactl --hardware
virsh vcpuinfo INSTANCE_DOMAIN
virsh emulatorpin INSTANCE_DOMAIN
virsh dumpxml INSTANCE_DOMAIN
# Guest VM
grep -E 'processor|physical id|core id' /proc/cpuinfo
lscpu
uptime
mpstat -P ALL 1 5
이 정도만 모아도 "스케줄링은 잘 됐는지", "게스트가 기대한 토폴로지를 보고 있는지" 정도는 꽤 빨리 감이 옵니다.
4. Nova CPU 스케줄링 설정 확인 포인트
이제 본론입니다. Nova CPU 스케줄링과 리소스 할당을 볼 때 저는 보통 nova.conf의 CPU 정책부터 확인합니다. 환경마다 값은 다를 수 있지만, 아래와 같은 항목들이 자주 등장합니다.
[DEFAULT]
cpu_allocation_ratio=4.0
ram_allocation_ratio=1.0
reserved_host_memory_mb=4096
[compute]
cpu_shared_set=2-15
cpu_dedicated_set=16-31
[libvirt]
virt_type=kvm
emulator_threads_policy=share
위 예시는 구조 설명용입니다. 특정 값이 정답이라는 뜻은 아닙니다. 다만 운영 의도는 분명해야 합니다. 예를 들어 cpu_shared_set와 cpu_dedicated_set를 섞어서 쓴다면, 어떤 워크로드를 공유형으로 둘지, 어떤 워크로드를 전용형으로 둘지 먼저 정해야 하거든요.
중요한 건 설정 파일의 숫자보다 정책 일관성입니다. 한 호스트는 전용 CPU 정책, 다른 호스트는 공유 정책인데 같은 aggregate(집합, 스케줄링 그룹)로 묶여 있으면 benchmark 결과가 해석 불가능해질 수 있습니다.
공유 CPU 세트, 전용 CPU 세트, 에뮬레이터 스레드 정책이 어떻게 나뉘는지 보여주는 설정 이미지입니다.
5. 리소스 할당 전략: 워크로드별로 다르게 가져가야 합니다
이 부분이 현업에서 진짜 중요합니다. 모든 인스턴스에 같은 정책을 적용하면 편하긴 한데, 성능과 밀도 둘 다 애매해지기 쉽습니다.
5-1. 일반 웹/배치 워크로드
- Shared CPU 기반 운영이 보통 효율적입니다.
- 적절한 오버커밋으로 집적도를 높일 수 있습니다.
- 대신 benchmark는 피크 시간과 비피크 시간을 나눠 봐야 합니다.
5-2. DB, 메시지 큐, 지연 민감 서비스
- Dedicated CPU 또는 CPU pinning 검토가 필요합니다.
- NUMA 정렬과 huge page를 함께 보는 편이 좋습니다.
- 가상 머신 성능 비교 시 평균값보다 tail latency(꼬리 지연)를 더 중시해야 합니다.
5-3. 혼합 클러스터 운영 팁
제 경험상 host aggregate(호스트 애그리게이트)와 flavor extra spec(플레이버 추가 속성)을 같이 쓰는 방식이 운영 설명력이 좋았습니다. 예를 들면 성능형 호스트 풀과 일반형 호스트 풀을 나누고, 성능형 flavor만 전용 CPU 정책으로 보내는 식이죠.
openstack flavor set perf.large \
--property hw:cpu_policy=dedicated \
--property hw:mem_page_size=large
openstack flavor set general.medium \
--property hw:cpu_policy=shared
이렇게 해두면 나중에 문제 생겼을 때 추적이 쉬워집니다. "왜 이 인스턴스는 빠르지?" 혹은 "왜 이건 느리지?"를 설명할 근거가 남거든요.
6. ⚠️ 실제로 자주 겪는 트러블슈팅
여기서는 제가 실제로 많이 부딪혔던 문제 위주로 적어보겠습니다. 문서만 보면 단순해 보이는데, 현장에서는 꼭 꼬입니다.
6-1. Pinning은 했는데 성능이 기대보다 안 나오는 경우
가장 먼저 NUMA 배치를 의심해보세요. vCPU는 한 소켓 쪽에 몰렸는데 메모리는 다른 NUMA 노드에서 잡히면 메모리 접근이 꼬일 수 있습니다. 이럴 때는 인스턴스 XML과 호스트 NUMA 정보를 같이 확인해야 합니다.
virsh dumpxml INSTANCE_DOMAIN | grep -i -E 'numa|vcpu|cputune|emulatorpin'
numactl --hardware
6-2. 동일한 벤치마크인데 결과 편차가 큰 경우
이건 noisy neighbor 가능성이 큽니다. 특히 공유형 CPU 정책에서는 배치 타이밍에 따라 차이가 꽤 납니다. 저도 처음엔 테스트 툴 문제인 줄 알았는데, 같은 호스트에 다른 VM이 CPU burst를 치고 있었더라고요.
6-3. 호스트는 여유 있는데 스케줄링이 실패하는 경우
Placement(플레이스먼트, 자원 추적 및 배치 서비스) 관점에서 자원 클래스(resource class, 자원 분류)나 trait(특성)이 안 맞는 경우가 있습니다. 숫자상 여유와 스케줄링 가능 여부는 다를 수 있습니다. 그래서 단순히 top만 보는 식으로는 원인 파악이 안 됩니다.
6-4. 에뮬레이터 스레드가 의외의 병목이 되는 경우
이거 놓치기 쉽습니다. 전용 CPU만 신경 쓰다가 emulator thread가 같은 코어에 얹혀서 변동성이 생기기도 하거든요. 성능 민감 워크로드라면 이 부분도 꼭 확인해보세요.
vCPU pinning, NUMA 노드, noisy neighbor 분석 지표를 함께 보는 트러블슈팅 예시 이미지입니다.
7. 검증은 이렇게 합니다: 가상 머신 성능 확인 절차
설정 바꾸고 느낌상 빨라진 것 같다고 끝내면 안 됩니다. 검증 절차를 남겨야 다음 변경 때도 비교가 되거든요. 저는 보통 아래 순서로 봅니다.
- 호스트 토폴로지 확인
- 인스턴스 배치 정책 확인
- 게스트 내부 CPU 인식 상태 확인
- 동일 조건으로 benchmark 반복 실행
- 평균값보다 편차와 최저 구간을 함께 비교
# Example benchmark flow inside guest
stress-ng --cpu 4 --timeout 60s --metrics-brief
sysbench cpu --threads=4 run
여기서 조심할 점은, 특정 툴의 점수 자체보다 반복 실행 시 일관성입니다. OpenStack Nova 성능 최적화가 잘 된 환경은 최고점만 높은 게 아니라, 여러 번 돌려도 편차가 상대적으로 줄어드는 경우가 많았습니다.
| 검증 항목 | 좋은 신호 | 경계 신호 |
|---|---|---|
| CPU 사용률 분포 | 예상 코어에 집중 | 임의 분산, 잦은 변동 |
| Benchmark 반복성 | 결과 편차 작음 | 실행마다 차이 큼 |
| NUMA 정렬 | CPU/메모리 지역성 유지 | 원격 메모리 접근 증가 |
| 호스트 안정성 | 예약 자원 충분 | 호스트 자체가 바쁨 |
드디어 됐다! 싶었던 순간도 사실 이런 표를 정리한 뒤에야 왔습니다. 그냥 체감이 아니라, 왜 결과가 좋아졌는지 설명이 되어야 다음 운영 변경에도 자신이 생기더라고요.
반복 벤치마크 결과의 편차 감소와 CPU 배치 안정성을 비교하는 결과 시각화 이미지입니다.
8. 정리와 다음 단계: 무엇부터 손대면 좋을까
정리해보면 OpenStack Nova 성능 최적화는 결국 세 가지입니다. 정책을 분리하고, 배치를 검증하고, 결과를 반복 측정하는 것이죠. Nova CPU 스케줄링은 단순 옵션 튜닝이 아니라, 워크로드 성격에 맞는 리소스 할당 전략을 설계하는 일에 가깝습니다.
- 일반 워크로드는 공유 정책과 적절한 오버커밋으로 효율을 봅니다.
- 민감한 워크로드는 전용 CPU, NUMA 정렬, 메모리 정책을 같이 봅니다.
- 가상 머신 성능 평가는 평균 점수보다 재현성과 편차를 함께 봐야 합니다.
- 벤치마크는 반드시 배치 정보와 같이 기록해야 의미가 있습니다.
혹시 이런 경험 있으신가요? 분명 스펙은 같은데 어떤 VM만 유독 느린 상황이요. 그런 경우라면 애플리케이션을 의심하기 전에 CPU 정책과 배치 상태부터 보시는 걸 추천드립니다. 생각보다 거기서 답이 나오는 경우가 많거든요.
다음 글에서는 Placement와 flavor extra spec을 조금 더 깊게 들어가서, 스케줄링 의도를 어떻게 코드처럼 관리할지 다뤄볼 예정입니다. 이전 글에서 다뤘던 가상화 호스트 기본 점검 내용과 함께 보시면 흐름이 더 잘 잡히실 겁니다.
공유 CPU와 전용 CPU 선택 기준, NUMA 체크포인트, 검증 절차를 요약한 인포그래픽 이미지입니다.
자주 묻는 질문
Q1. CPU overcommit을 무조건 낮추면 성능이 좋아지나요?
항상 그렇진 않습니다. 집적도가 너무 낮아져 운영 효율이 떨어질 수 있고, 워크로드 특성상 공유 정책으로도 충분한 경우가 있습니다.
Q2. Nova CPU 스케줄링만 조정하면 끝인가요?
아닙니다. libvirt 설정, NUMA 구조, 메모리 정책, 게스트 OS 튜닝까지 함께 봐야 합니다.
Q3. benchmark 결과가 매번 다르면 무엇부터 확인해야 하나요?
테스트 시간대, noisy neighbor, 배치 호스트, NUMA 정렬, 에뮬레이터 스레드 정책 순으로 점검해보시면 됩니다.
'IT > openstack' 카테고리의 다른 글
| [OpenStack] DevStack 환경에서 OpenStack 서비스 간 연동 문제 해결 가이드 (1) | 2026.07.20 |
|---|---|
| [OpenStack] OpenStack Glance 이미지 관리, 효율적인 스토리지 활용 전략 (1) | 2026.07.20 |
| [OpenStack] OpenStack Keystone 인증 시스템, 1년 운영 후기 및 보안 강화 팁 (0) | 2026.07.19 |
| [인프라] OpenStack Ironic으로 베어메탈 서버 자동 프로비저닝 실전 사례 (0) | 2026.07.19 |
| [스토리지] OpenStack Swift vs Ceph 선택 기준 심층 비교 (0) | 2026.07.16 |
| [OpenStack] 오픈스택 플레이버 최적화로 유휴 자원 줄이기 (0) | 2026.07.10 |