10 KiB
id, kind, slug, title, topic, topicName, project, status, basisVersion, studio, sourceRevision, assets, source
| id | kind | slug | title | topic | topicName | project | status | basisVersion | studio | sourceRevision | assets | source | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ebdf93d7-2dcb-4fc8-91b9-2364ac8196e6 | CONCEPT | virtio-balloon-memory-reclaim | virtio-balloon 이 Guest 메모리를 회수하고 돌려주는 방식 | memory-virtualization | 메모리 가상화 | virtualization | 초안 | virtio-balloon — Guest kernel 쪽 driver 와 QEMU 쪽 device 가 virtqueue 로 맞물린 구성 · libvirt 의 balloon target | https://hyeonworks.com/studio/documents/ebdf93d7-2dcb-4fc8-91b9-2364ac8196e6/edit | no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다 |
|
|
virtio-balloon 이 Guest 메모리를 회수하고 돌려주는 방식
호스트는 QEMU 가 마련한 게스트 RAM 을 볼 수 있지만 그 안에서 어떤 메모리가 중요한지는 알지 못한다. 그 구분을 아는 쪽은 게스트 커널이라, 호스트가 그 메모리를 그냥 스왑으로 밀어내는 대신 게스트와 협력해 필요 없는 몫을 돌려받는 방법이 따로 있다. virtio-balloon 이 그 협력에 쓰는 가상 장치다. 게스트 안의 드라이버와 QEMU 쪽 장치가 virtqueue 로 맞물려 있어서, 호스트가 balloon target 을 올리면 게스트 안의 balloon 이 커지고 게스트가 쓸 수 있는 메모리가 줄며 호스트가 회수할 수 있는 몫이 는다. 값을 낮추면 반대 방향으로 움직인다. 이 장치는 게스트에 RAM 을 더 주는 장치가 아니라 이미 준 용량 안에서 쓸 수 있는 양을 옮기는 장치이고, 과도하게 회수하면 호스트 RAM 을 확보하려던 조치가 게스트를 압박한다.
관계
- Host 메모리 압박이 Guest 와 스토리지까지 내려가는 경로 ballooning 은 그 압박에 대응하는 수단 가운데 하나다. 호스트가 무작정 스왑으로 밀어낼 때 무엇이 일어나는지는 그쪽에 적혀 있다.
- 이 가상 머신들에 virtio-balloon 이 붙어 있는가 이 프로젝트의 가상 머신에 이 장치가 구성돼 있는지는 근거 문서에 없다. 그것을 확인하는 질문이다.
- balloon target 을 바꾸면 게스트가 쓸 수 있는 메모리는 어떻게 따라 움직이는가 부풀리고 줄이는 방향은 이 글이 적었고, 이 환경에서 얼마나 어떤 속도로 반영되는지는 그 질문이 잰다.
- 메모리 증상 하나로 계층을 단정하지 않는다 balloon target 은 그 기준이 가르는 다섯 갈래 중 Dynamic Memory 갈래다. 게스트 안의 압박을 보고 호스트 RAM 부족으로 넘기기 전에 이 값을 본다.
본문
호스트는 게스트 안에서 무엇이 중요한지 알지 못한다
호스트는 QEMU 가 마련한 게스트 RAM 을 볼 수 있다. 그러나 그 안에서 어떤 메모리가 중요한지는 게스트 밖에서 완전히 알 수 없다. 게스트는 자기 메모리를 애플리케이션이 실제로 쓰는 몫(working set)과 JVM heap, 페이지 캐시, 비어 있는 몫처럼 의미가 다른 묶음으로 구분해 알고 있다. 호스트가 보는 것은 같은 크기의 익명 메모리라서 그 안에서 페이지 캐시를 눌렀는지 실제로 쓰는 몫을 눌렀는지 가려낼 수 없다.
그래서 호스트가 그 메모리를 무작정 스왑으로 밀어내기보다 게스트 커널과 협력해 필요 없는 몫을 돌려받는 편이 유리할 수 있다. 그 협력에 쓰는 대표적인 메커니즘이 virtio-balloon 이다.
게스트 드라이버와 QEMU 장치가 virtqueue 로 맞물린다
virtio-balloon 은 게스트 커널 쪽의 balloon 드라이버와 QEMU 쪽의 balloon 장치가 virtqueue 로 이어진 구성이다. virtqueue 는 게스트와 QEMU 가 요청과 응답을 주고받는 공유 큐이고, balloon 관련 요청도 이 큐를 지나 VM 경계를 넘는다. QEMU 쪽 장치는 받은 내용을 호스트의 메모리 관리로 넘긴다.
이 장치는 게스트 RAM 자체를 제공하지 않는다. 이미 존재하는 게스트 RAM 을 호스트와 게스트가 협력해 회수하고 반환하는 데 쓰는 가상 장치다.
이 프로젝트의 가상 머신에 이 장치가 붙어 있는지는 근거 문서에 없다. 아래 두 절이 적는 것은 장치가 있을 때 어느 방향으로 움직이는가다.
Inflate — 게스트 안의 balloon 이 커진다
호스트가 게스트 메모리를 회수하려고 하면 balloon target 을 조정해 balloon 을 부풀린다. 이 동작을 inflate 라고 한다. 그 요청이 virtio-balloon 을 지나 게스트 안의 balloon 드라이버에 닿으면 드라이버가 게스트 페이지를 확보한다. 게스트 안의 balloon 이 커지기 때문에 게스트가 쓸 수 있는 RAM 이 그만큼 줄고, 호스트 쪽에서는 회수할 수 있는 메모리가 는다.
드라이버가 하는 일은 확보한 페이지를 일반적인 게스트 작업이 쓰지 못하도록 붙잡아 두고 그 사실을 호스트 쪽에 알리는 것까지다. 그 뒤 호스트가 그 메모리를 실제로 언제 어떻게 놓아주는지는 QEMU/KVM 버전과 backing 종류 및 설정에 따라 달라질 수 있다. 근거 문서는 그 동작을 하나로 단정하지 않았고 이 환경에서도 확인하지 않았다. 그 문서는 이 호스트의 QEMU/KVM 버전을 한 번도 적지 않았다. 버전과 설정이 갈라 놓는 동작이라 버전을 적기 전에는 이 환경이 어느 쪽인지 말할 수 없다.
Deflate — target 을 줄이면 되돌아온다
호스트가 게스트에게 메모리를 다시 내줄 수 있으면 balloon target 을 줄인다. 그러면 게스트 balloon 드라이버가 붙잡고 있던 페이지를 반환하고 게스트가 쓸 수 있는 메모리가 늘어난다.
| 호스트가 balloon target 을 | 게스트가 쓸 수 있는 메모리는 |
|---|---|
| 올린다 (Inflate) | 감소 |
| 내린다 (Deflate) | 증가 |
과도한 inflate 가 게스트를 압박한다
게스트 애플리케이션이 실제로 쓰는 메모리가 큰데 balloon 을 과도하게 부풀리면, 게스트가 쓸 수 있는 메모리가 줄면서 게스트 안에 메모리 압박이 생긴다. 그러면 게스트 안에서 회수가 돌고 페이지 캐시가 회수되고 게스트 스왑이 시작되며, 심하면 게스트 OOM(Out Of Memory)까지 간다.
호스트 RAM 을 확보하려는 조치가 게스트의 스토리지 I/O 와 애플리케이션 지연을 늘릴 수 있다는 뜻이다. 회수한 만큼 호스트가 편해지는 대신 게스트가 그 압박을 받으므로, balloon target 을 어디까지 올릴지는 게스트가 실제로 쓰는 메모리를 보고 정한다.
ballooning 과 memory hotplug 는 같은 것이 아니다
ballooning 은 게스트에 이미 설정된 메모리 용량 안에서 호스트와 게스트 사이의 쓸 수 있는 양을 회수하고 반환한다. 용량 자체는 그대로다. memory hotplug 는 기존 게스트 RAM 에 메모리 장치나 영역을 더해 게스트가 늘어난 용량을 인식하게 한다. 하나는 이미 준 용량 안에서 쓸 수 있는 양을 옮기고 다른 하나는 용량을 더한다.
현대 가상화에는 virtio-mem 같은 다른 동적 메모리 관리 방식도 있어서, 가상 머신의 동적 메모리 관리를 ballooning 하나로 일반화하지 않는다. 근거 문서에 있는 것은 그런 방식이 존재한다는 사실까지다.
근거 문서가 번호를 붙여 둔 문장
근거 문서는 이 장치에서 고정한 문장에 번호를 붙여 두었다. 실험 기록에서 어느 문장을 확인했는지 가리킬 때 이 번호를 쓴다.
| 번호 | 근거 문서가 고정한 문장 |
|---|---|
| CLAIM-MEM-15 | virtio-balloon은 Guest와 Host가 memory 회수/반환에 협력하기 위한 가상 장치이며 RAM 자체를 제공하는 장치는 아니다. |
| CLAIM-MEM-16 | Balloon inflate가 과도하면 Guest reclaim/swap/OOM을 유발할 수 있다. |
이 문서가 확정하지 않는 것
이 글이 확정하는 것은 balloon 이 어떤 구조로 어느 방향으로 동작하는가까지다. 이 테스트 서버에서 잰 값은 하나도 없다.
이 프로젝트의 가상 머신에 virtio-balloon 이 붙어 있는지조차 근거 문서에 적혀 있지 않다. libvirt 설정에 balloon 관련 요소가 있는지, 있다면 게스트 안에서 그 드라이버가 어떤 이름으로 올라와 있는지를 먼저 확인해야 한다. 장치가 없으면 balloon target 실험은 성립하지 않는다.
값을 한 단계 바꿨을 때 게스트가 쓸 수 있는 메모리가 얼마나 움직이는지, 그 반영이 즉시인지 늦는지, 어느 값부터 게스트 안에서 회수와 스왑이 시작되는지도 재지 않았다. 호스트가 그 메모리를 언제 놓아주는지가 이 QEMU 버전과 이 backing 설정에서 어떻게 되는지도 마찬가지다. 두 확인은 각각 열린 질문으로 두었고 관계에 걸어 두었다.