Virtualização, atualmente, significa mais do que apenas consolidar servidores subutilizados. Ultrapassamos a época em que a virtualização em x86 era apenas utilizada para cargas de trabalho pequenas, dada as limitações de escalabilidade e o impacto no desempenho causado pelo hypervisor.
Parece que chegou a vez dos grandes servidores terem o seu lugar ao sol, ou melhor, na nuvem.
E até onde o KVM pode chegar?
Vejamos alguns limites do KVM no Red Hat Enteprise Linux 6:
Número máximo de vCPUs para uma máquina virtual | 160 |
Quantidade máxima de memória para uma máquina virtual | 2 TB |
São números suficientemente grandes para a maioria das cargas de trabalho existentes.
O fato do KVM estar integrado ao kernel do Linux dá-lhe a possibilidade de aproveitar seus recursos bastante estáveis e eficientes, como o escalonamento de processos, gerenciamento de memória e I/O. Todas estas tecnologias colaboram com sua escalabilidade e, sobretudo, com seu desempenho.
Entretanto, devemos observar algumas características e configurações para conseguirmos extrair o máximo de desempenho das máquinas virtuais com configurações altas. A topologia do NUMA é uma delas.
O que é NUMA?
Historicamente, toda memória em um sistema x86 era igualmente acessada por todas as CPUs. Conhecido como Uniform Memory Access (UMA), o tempo de acesso era exatamente o mesmo, não importando qual CPU executava o processo.
Este comportamento foi alterado nos sistemas x86 mais recentes. No Non-Uniform Memory Access (NUMA), toda memória do sistema é dividida em zonas, chamados de nodes, que são alocados para um determinado CPU ou socket. Sendo assim, um processo consegue acessar sua memória local mais rapidamente que a memória remota (memória local de outro processador ou memória compartilhada entre os processadores).
Sistema NUMA típico com dois nodes
Na figura acima, o CPU2 é um core que pertence ao NUMA Node A e, portanto, um processo executado por ele irá acessar a memória local mais rapidamente do que a memória do Node B, já que para chegar nesta memória é necessário utilizar outro barramento, representado na figura pelo Cross-Node Link.
O problema
Em um servidor bare-metal típico, as versões mais recentes dos principais sistemas operacionais sabem como lidar com o NUMA, otimizando o acesso à memória de acordo com o processador e o seu respectivo node.
Mas quando adicionamos virtualização, tratando-se especificamente do KVM, o sistema operacional virtualizado não tem conhecimento da topologia do NUMA, afetando sua capacidade de otimizar a alocação de memória ao escalonar os processos.
Este cenário fica mais evidente quando executamos máquinas virtuais com configurações altas (maior quantidade de vCPUs e memória), pois aumenta-se o risco de seus respectivos vCPUs e memória não estarem nos mesmos nodes.
E não é apenas a localização dos dados na memória que importa. O número de nodes dentro de uma máquina virtual afeta diretamente o desempenho do sistema, pois é necessário gerenciar os locks para acessá-los, ou seja, quanto maior o número de nodes, maior a divisão destes locks e, consequentemente, menor é a contenção.
A solução
Uma saída para otimizarmos o desempenho em relação a topologia do NUMA é através das configurações de tuning de CPU do KVM, onde é possível fixar os CPUs físicos para uma determinada máquina virtual.
No exemplo de configuração a seguir, especificamos que os 8 vCPUs da nossa máquina virtual executará seus processos nos CPUs físicos de 0 a 7. Também associamos cada vCPU a um determinado CPU físico. Por exemplo, o vCPU0 estará preso ao CPU físico 0, vCPU1 ao CPU físico 1, e assim por diante.
<cputune>
<vcpupin vcpu=’0′ cpuset=’0’/>
<vcpupin vcpu=’1′ cpuset=’1’/>
<vcpupin vcpu=’2′ cpuset=’2’/>
<vcpupin vcpu=’3′ cpuset=’3’/>
<vcpupin vcpu=’4′ cpuset=’4’/>
<vcpupin vcpu=’5′ cpuset=’5’/>
<vcpupin vcpu=’6′ cpuset=’6’/>
<vcpupin vcpu=’7′ cpuset=’7’/>
</cputune>
E supondo que estes 8 vCPUs estejam divididos em dois NUMA nodes, podemos usar a configuração a seguir para definirmos a topologia do NUMA em nossa máquina virtual.
<numa>
<cell cpus=’0-3′ memory=’512000’/>
<cell cpus=’4-7′ memory=’512000’/>
</numa>
</cpu>
Com o conhecimento da topologia do NUMA no servidor físico, podemos trabalhar com estas configurações para fixarmos os vCPUs e definirmos a topologia da máquina virtual, maximizando a alocação de memória em nodes específicos.
Automatizando
Como vimos, é relativamente fácil fixarmos os CPUs e configurarmos a topologia do NUMA manualmente para uma máquina virtual no KVM. Entretanto, mesmo essas configurações podem não ser as melhores em determinados momentos, tendo em vista o dinamismo das cargas de trabalho.
Adicionalmente, ajustes manuais devem ser evitados para não comprometer outras vantagens do sistema de virtualização, como a alta disponibilidade, migração a quente e a própria capacidade de consolidação.
Considerando este cenário, as versões mais recentes do kernel do Linux implementa o recurso AutoNUMA, cujo objetivo é estabelecer as ligações dos processos (incluindo as máquinas virtuais do KVM) com os CPUs físicos dinamicamente, buscando extrair o máximo de desempenho em relação a topologia do NUMA.
Este recurso não existe no kernel do Red Hat Enterprise Linux 6, porém, ele é habilitado por padrão no Red Hat Enterprise Linux 7.
Para verificar o status do AutoNUMA no Red Hat Enterprise Linux 7, utilize o comando:
# cat /sys/kernel/debug/sched_features
Para desabilitá-lo:
# echo NONUMA > /sys/kernel/debug/sched_features
E para habilitá-lo:
# echo 1 > /sys/kernel/mm/autonuma/enabled
O AutoNUMA traz ganhos significativos de desempenho. Desabilitá-lo faz sentido apenas quando o overhead gerado pelos seus cálculos e processo de realocação de memória seja perceptível em cargas de trabalho mais críticas. Neste caso, recomenda-se fazer a configuração manualmente.
Referências
Red Hat. Virtualization limits for Red Hat Enterprise Linux hypervisors. Red Hat Resource Library. Acessado em 04-02-2014.
Red Hat. Domain XML format.Libvirt documentation. Acessado em 04-02-2014.
Arcangeli,Andrea (08-2012). Automatic NUMA CPU Scheduling and Memory Migration .Linux Plumbers Conference. Acessado em 05-02-2014.
Theurer, Andrew (05-2012). KVM and Big VMs. KVM Forum 2012. Acessado em 05-02-2014.
Olá Heitor. parabéns pelo post, ficou bem claro e objetivo.
Massaa Parabens pela explicação!