7.8 KiB
id, kind, slug, title, topic, topicName, project, status, questionStatus, studio, sourceRevision, source
| id | kind | slug | title | topic | topicName | project | status | questionStatus | studio | sourceRevision | source | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| eba4a877-276a-4050-9a97-d32614546c71 | QUESTION | vcpu-contention-under-two-vm-load | 가상 머신 두 대에 동시에 부하를 주면 이 호스트에서 vCPU 경쟁이 실제로 생기는가 | cpu-virtualization | CPU 가상화 | virtualization | 초안 | OPEN | https://hyeonworks.com/studio/documents/eba4a877-276a-4050-9a97-d32614546c71/edit | no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다 |
|
가상 머신 두 대에 동시에 부하를 주면 이 호스트에서 vCPU 경쟁이 실제로 생기는가
Keycloak 멀티 노드 실험은 물리 호스트 한 대 위의 가상 머신 두 대에서 돌아간다. 두 가상 머신이 동시에 CPU 를 많이 쓰면 QEMU vCPU 스레드끼리 호스트 CPU 시간을 두고 경쟁할 수 있다. 그런데 이 호스트에 논리 CPU 가 몇 개인지도, 두 가상 머신에 vCPU 를 몇 개씩 줬는지도 문서에 적혀 있지 않아 경쟁이 생길 조건인지부터 모른다.
관계
- KVM 에서 vCPU 가 물리 CPU 에서 실행되기까지 vCPU 스레드가 호스트 Linux 스케줄러를 거쳐 논리 CPU 에 배치되는 경로를 이 개념이 설명한다.
- 가상 머신 두 대를 CPU-bound 로 만들면 게스트 steal time 은 얼마나 오르는가 같은 부하를 걸고 게스트 쪽 지표만 따로 묻기 때문에, 호스트 쪽 지표까지 한 번에 찍으면 두 질문이 같은 측정으로 닫힌다. 한 물음으로 합칠지는 값을 잰 뒤에야 알 수 있어 지금은 둘로 두고 관계로만 이었다.
사실
§12 는 호스트에 논리 CPU 가 12개 있고 8 vCPU 짜리 가상 머신 넷을 올린 예를 드는데, 그러면 총 32 vCPU 가 12개의 논리 CPU 위에서 실행될 수 있다.
모든 가상 머신이 동시에 CPU 를 많이 사용하면 vCPU 스레드끼리 호스트 CPU 시간을 두고 경쟁한다 : §12 이런 상황에서는 게스트 안의 애플리케이션이 느려졌더라도 원인이 그 애플리케이션이 아니라 호스트 CPU 경쟁일 수 있다 : §12
§16 이 그린 테스트 환경은 Physical Host 아래 Host Nginx 와 가상 머신 두 대이고, VM 1 과 VM 2 가 각각 K3s 노드와 Keycloak 을 돌린다.
§16 이 결과 해석에서 분리하라고 든 원인 일곱
Keycloak refresh/session 동시성 PostgreSQL contention/locking Redis 상태 관리 K3s resource scheduling VM vCPU scheduling Host CPU saturation Nginx/LB
§20 이 이 물음의 확인 대상으로 든 다섯
Host logical CPU 수 각 VM vCPU 수 QEMU vCPU thread CPU 사용량 Host run queue Guest steal time
이 호스트의 논리 CPU 수 : 문서에 없음 두 가상 머신의 vCPU 수 : 문서에 없음
§12 의 12 와 8 과 32 는 경쟁이 어떻게 생기는지 설명하려고 든 예시 숫자이지 이 호스트에서 읽은 값이 아니다.
가정
두 가상 머신은 같은 물리 호스트의 CPU 를 나눠 쓴다. §16 이 그린 구조가 지금 실험 환경과 같다고 전제한다.
두 가상 머신에 같은 시각에 CPU 부하를 걸 수 있고, 그때 호스트와 두 게스트의 지표를 같은 시각에 기록할 수 있다.
게스트 Linux 의 top 이 이 환경에서 %st 를 실제로 채워 준다. %st 열이 보여 주는 steal time 은 게스트의 vCPU 에 실행할 작업이 있는데도 다른 작업 때문에 곧바로 실행되지 못한 상황을 가리킨다(§13). 이 열이 비면 게스트 쪽에서는 경쟁의 단서를 못 본다.
호스트 쪽 Nginx 도 같은 물리 CPU 를 쓰는데, 부하 구간의 호스트 CPU 사용량을 전부 QEMU vCPU 스레드 몫으로 읽으면 이 전제가 깨진다.
미지수
이 호스트의 논리 CPU 수.
두 가상 머신에 준 vCPU 수와 그 합. 그 합이 논리 CPU 수를 넘는지.
부하를 걸기 전 QEMU vCPU 스레드의 CPU 사용량과 호스트의 실행 대기열(run queue), 그리고 두 게스트의 %st. 부하 전 값이 없으면 부하 중 값만 가지고는 그 값이 움직인 것인지 판정할 수 없다.
두 가상 머신에 동시에 부하를 걸었을 때 그 세 지표가 어떻게 움직이는지.
vCPU 합이 논리 CPU 수 이하인데도 %st 가 오르는 구간이 있는지.
제약
이 호스트에서 잰 값이 하나도 없다. 근거는 개념을 정리한 문서 한 편이고 §12 의 숫자는 예시다.
§20 이 확인 대상을 다섯으로 잡았으므로 steal time 하나만 찍고 닫을 수 없다. 호스트 쪽 사용량과 실행 대기열도 함께 본다. 이 물음은 닫는 조건이 없다고 보아 한 번 기록에서 뺐다가 되돌렸다. §20 이 이미 적어 둔 확인 대상 다섯이 그대로 닫는 조건이 되기 때문이다.
§16 은 CPU 가상화가 Keycloak refresh token 경쟁의 원인은 아니라고 못박는다. 이 질문은 원인을 찾으려는 것이 아니라 실험 결과를 어느 계층 쪽으로 읽을지 가르는 데 쓴다.
측정하는 동안 실험 환경 구성은 바꾸지 않는다. pinning 을 걸거나 vCPU 수를 줄이면 지금 구성에서 경쟁이 생기는지를 못 본다.
선택지
1. 호스트 논리 CPU 수와 각 가상 머신의 vCPU 수를 먼저 읽는다
이 두 값은 부하를 걸지 않고도 지금 읽을 수 있다. 둘만 있으면 vCPU 합이 논리 CPU 수를 넘는지 갈리고, 넘지 않는 구성이라면 §12 가 든 32 대 12 같은 초과 할당 상태는 아니라는 것까지 확정된다. 움직이는 나머지 셋은 그 뒤에 잰다.
2. 다섯 지표를 부하 전과 부하 중 두 시점에 찍는다
부하를 걸기 전에 한 번, 두 가상 머신에 동시에 부하를 건 뒤에 한 번, 같은 명령으로 기록한다. 호스트 쪽은 ps -eLo pid,tid,psr,pcpu,comm | grep qemu 로 QEMU vCPU 스레드를 보고, 게스트 쪽은 top 으로 %st 를 본다.
3. 가상 머신 한 대에만 먼저 부하를 걸어 본다
한 대만 걸었을 때 지표가 어떻게 움직이는지 알아 두면, 두 대를 동시에 걸었을 때 늘어난 값이 vCPU 경쟁 때문인지 그 가상 머신 안의 CPU 포화 때문인지 갈린다. 다만 이 질문은 두 대를 동시에 돌렸을 때를 묻기 때문에 이 측정만으로는 닫히지 않는다.
4. 제외 — pinning 을 걸어 놓고 잰다
vCPU 스레드를 특정 논리 CPU 에 고정하면 경쟁 구간을 만들기 쉽다. 그러나 지금 구성에서 경쟁이 생기는지를 묻는 질문이라, 구성을 바꾸고 잰 값은 답이 되지 않는다. pinning 은 별도 질문으로 뺀다.
다음 검증
- 호스트 논리 CPU 수와 각 가상 머신의 vCPU 수를 먼저 적는다. §20 이 든 확인 대상 다섯 가운데 부하 없이 읽을 수 있는 둘이다.
- 부하를 걸기 전에 호스트에서 ps -eLo pid,tid,psr,pcpu,comm | grep qemu (§14.7) 로 QEMU vCPU 스레드의 CPU 사용량을, 호스트 실행 대기열을, 두 게스트에서 top (§14.8) 으로 %st 를 같은 시각에 기록한다.
- VM 1 과 VM 2 에 동시에 CPU 부하를 건다.
- 부하 중에 2번의 세 지표를 같은 방법으로 다시 기록한다.
닫는 조건 : 두 가상 머신의 vCPU 합이 호스트 논리 CPU 이하이고 동시 부하에서도 게스트 %st 와 호스트 실행 대기열이 부하 전과 다르지 않으면, 이 호스트 구성에서는 경쟁이 관측되지 않는다고 적고 닫는다. %st 나 실행 대기열이 움직이면 그 부하 전후 표가 Case 가 되고 이 질문은 그 Case 가 닫는다. vCPU 수를 줄일지 가상 머신 배치를 바꿀지는 그 Case 가 나온 뒤 Decision 으로 넘긴다.