Roubar: quen rouba o tempo do procesador das máquinas virtuais

Roubar: quen rouba o tempo do procesador das máquinas virtuais

Ola! Quero falarvos en termos sinxelos da mecánica do roubo dentro das máquinas virtuais e dalgúns artefactos non obvios que conseguimos descubrir durante a súa investigación, nos que tiven que mergullarme como director técnico dunha plataforma na nube. Solucións na nube Mail.ru. A plataforma funciona en KVM.

O tempo de roubo da CPU é o tempo durante o cal a máquina virtual non recibe recursos do procesador para a súa execución. Este tempo só se conta nos sistemas operativos convidados en contornas de virtualización. As razóns de onde van estes recursos máis asignados, como na vida, son moi vagas. Pero decidimos descubrilo, e mesmo realizamos unha serie de experimentos. Non é que agora saibamos todo sobre roubo, pero xa vos contaremos algo interesante.

1. Que é roubar

Polo tanto, o roubo é unha métrica que indica a falta de tempo do procesador para os procesos dentro dunha máquina virtual. Como se describe no parche do núcleo KVMO furtivo é o tempo durante o cal o hipervisor está a executar outros procesos no sistema operativo anfitrión aínda que puxo en cola o proceso da máquina virtual para a súa execución. É dicir, o roubo calcúlase como a diferenza entre o momento no que o proceso está listo para executarse e o momento no que se lle asigna o tempo de procesador ao proceso.

O núcleo da máquina virtual recibe a métrica de roubo do hipervisor. Ao mesmo tempo, o hipervisor non especifica exactamente que outros procesos está a executar, simplemente di "mentres estou ocupado, non podo darche tempo". En KVM, engadiuse soporte para o cálculo de roubos parches. Aquí hai dous puntos clave:

  • A máquina virtual aprende sobre o roubo do hipervisor. É dicir, desde o punto de vista das perdas, para os procesos na propia máquina virtual trátase dunha medida indirecta que pode estar suxeita a diversas distorsións.
  • O hipervisor non comparte información coa máquina virtual sobre o que máis está a facer; o principal é que non lle dedica tempo. Debido a isto, a propia máquina virtual non pode detectar distorsións no indicador de roubo, que poderían ser avaliados pola natureza dos procesos competidores.

2. O que afecta ao roubo

2.1. Roubar cálculo

Esencialmente, o roubo calcúlase aproximadamente o mesmo que o tempo de utilización normal da CPU. Non hai moita información sobre como se considera a reciclaxe. Probablemente porque a maioría da xente considera esta pregunta obvia. Pero aquí tamén hai trampas. Para familiarizarse con este proceso, pode ler artigo de Brendan Gregg: aprenderá sobre moitos matices ao calcular a utilización e sobre situacións nas que este cálculo será erróneo polos seguintes motivos:

  • O procesador sobrequenta, o que fai que se salten os ciclos.
  • Activa/desactiva o turbo boost, que cambia a velocidade do reloxo do procesador.
  • Un cambio na duración do intervalo de tempo que se produce cando se usan tecnoloxías de aforro de enerxía do procesador, como SpeedStep.
  • O problema co cálculo da media: estimar a utilización dun minuto nun 80% pode ocultar unha explosión a curto prazo do 100%.
  • Un bloqueo de rotación fai que se recupere o procesador, pero o proceso do usuario non ve ningún progreso na súa execución. Como resultado, a utilización calculada do procesador polo proceso será cen por cento, aínda que o proceso non consumirá fisicamente o tempo do procesador.

Non atopei un artigo que describa un cálculo similar para roubar (se o sabes, compárteo nos comentarios). Pero, a xulgar polo código fonte, o mecanismo de cálculo é o mesmo que para a reciclaxe. Simplemente, engádese outro contador no núcleo, directamente para o proceso KVM (proceso da máquina virtual), que conta a duración do proceso KVM á espera do tempo da CPU. O contador toma información sobre o procesador da súa especificación e verifica se todas as súas marcas son utilizadas polo proceso da máquina virtual. Se iso é todo, entón supoñemos que o procesador só estaba ocupado co proceso da máquina virtual. En caso contrario, informamos de que o procesador estaba facendo outra cousa, apareceu roubo.

O proceso de reconto de roubos está suxeito aos mesmos problemas que o reconto regular de reciclaxe. Non quere dicir que estes problemas aparezan a miúdo, pero parecen desalentadores.

2.2. Tipos de virtualización en KVM

En liñas xerais, hai tres tipos de virtualización, todos eles compatibles con KVM. O mecanismo de aparición de roubos pode depender do tipo de virtualización.

Emisión. Neste caso, o funcionamento do sistema operativo da máquina virtual con dispositivos de hipervisor físico ocorre algo así:

  1. O sistema operativo convidado envía un comando ao seu dispositivo convidado.
  2. O controlador do dispositivo convidado recibe o comando, xera unha solicitude para o BIOS do dispositivo e envíao ao hipervisor.
  3. O proceso do hipervisor traduce comando en comando para o dispositivo físico, facéndoo, entre outras cousas, máis seguro.
  4. O controlador do dispositivo físico acepta o comando modificado e envíao ao propio dispositivo físico.
  5. Os resultados da execución de ordes van polo mesmo camiño.

A vantaxe da tradución é que permite emular calquera dispositivo e non require unha preparación especial do núcleo do sistema operativo. Pero hai que pagar por iso, en primeiro lugar, en velocidade.

Virtualización de hardware. Neste caso, o dispositivo a nivel de hardware comprende os comandos do sistema operativo. Este é o xeito máis rápido e mellor. Pero, desafortunadamente, non é compatible con todos os dispositivos físicos, hipervisores e sistemas operativos convidados. Actualmente, os principais dispositivos que admiten a virtualización de hardware son os procesadores.

Paravirtualización. A opción máis común para a virtualización de dispositivos en KVM e, en xeral, o modo de virtualización máis común para os sistemas operativos convidados. A súa peculiaridade é que o traballo con algúns subsistemas de hipervisor (por exemplo, coa rede ou a pila de discos) ou a asignación de páxinas de memoria prodúcese mediante a API do hipervisor, sen traducir comandos de baixo nivel. A desvantaxe deste método de virtualización é que o núcleo do sistema operativo convidado debe modificarse para que poida comunicarse co hipervisor mediante esta API. Pero isto adoita resolverse instalando controladores especiais no sistema operativo convidado. En KVM chámase esta API virtio API.

Coa paravirtualización, en comparación coa difusión, o camiño cara ao dispositivo físico redúcese significativamente ao enviar comandos directamente desde a máquina virtual ao proceso do hipervisor do host. Isto permítelle acelerar a execución de todas as instrucións dentro da máquina virtual. En KVM, isto faise mediante a API virtio, que só funciona para determinados dispositivos, como un adaptador de rede ou de disco. É por iso que os controladores de virtio instálanse dentro das máquinas virtuais.

A desvantaxe desta aceleración é que non todos os procesos que se executan dentro da máquina virtual permanecen dentro dela. Isto crea algúns efectos especiais que poden provocar a aparición de roubos. Recomendo comezar un estudo detallado deste problema con Unha API para E/S virtual: virtio.

2.3. Programación "xusta".

Unha máquina virtual nun hipervisor é, de feito, un proceso común que obedece ás leis de programación (distribución de recursos entre procesos) no núcleo de Linux, así que vexámolo máis de cerca.

Linux usa o chamado CFS, Completely Fair Scheduler, que se converteu no programador predeterminado desde o núcleo 2.6.23. Para entender este algoritmo, podes ler a arquitectura do núcleo de Linux ou o código fonte. A esencia do CFS é distribuír o tempo do procesador entre procesos dependendo da duración da súa execución. Canto máis tempo de CPU require un proceso, menos tempo de CPU recibe. Isto garante que todos os procesos se executen "de forma xusta", de xeito que un proceso non ocupe constantemente todos os procesadores e outros procesos tamén se poden executar.

Ás veces, este paradigma leva a artefactos interesantes. Os usuarios de Linux desde hai moito tempo probablemente recorden a conxelación dun editor de texto normal nun escritorio mentres executaban aplicacións de uso intensivo de recursos, como un compilador. Isto ocorreu porque as tarefas sen uso intensivo de recursos en aplicacións de escritorio competían coas tarefas de uso intensivo de recursos, como o compilador. CFS pensa que isto é inxusto, polo que detén periodicamente o editor de texto e deixa que o procesador se encargue das tarefas do compilador. Isto corrixiuse mediante un mecanismo sched_autogroup, pero mantivéronse moitas outras características da distribución do tempo do procesador entre tarefas. En realidade, esta non é unha historia sobre o mal que está todo en CFS, senón un intento de chamar a atención sobre o feito de que a distribución "xusta" do tempo do procesador non é a tarefa máis trivial.

Outro punto importante do planificador é a preferencia. Isto é necesario para expulsar o proceso de risa do procesador e deixar que outros traballen. O proceso de expulsión chámase cambio de contexto, cambio de contexto do procesador. Neste caso, consérvase todo o contexto da tarefa: o estado da pila, rexistros, etc., despois de que se envía o proceso a esperar, e outro ocupa o seu lugar. Esta é unha operación cara para o sistema operativo e úsase raramente, pero non hai nada de malo inherentemente. O cambio de contexto frecuente pode indicar un problema no SO, pero normalmente é continuo e non indica nada en particular.

Precísase unha historia tan longa para explicar un feito: cantos máis recursos de procesador intente consumir un proceso nun programador Linux honesto, máis rápido se deterá para que outros procesos tamén poidan funcionar. Se isto é correcto ou non é unha cuestión complexa que se pode resolver de forma diferente baixo diferentes cargas. En Windows, ata hai pouco, o programador estaba centrado no procesamento prioritario das aplicacións de escritorio, o que podía provocar que se conxelan os procesos en segundo plano. Sun Solaris tiña cinco clases diferentes de programadores. Cando lanzamos a virtualización, engadimos un sexto, Programador de compartición xusta, porque os cinco anteriores non funcionaban adecuadamente coa virtualización de Solaris Zones. Recomendo comezar un estudo detallado desta cuestión con libros como Solaris Internals: Solaris 10 e OpenSolaris Kernel Architecture ou Comprensión do núcleo de Linux.

2.4. Como controlar o roubo?

O seguimento do roubo dentro dunha máquina virtual, como calquera outra métrica do procesador, é sinxelo: podes usar calquera ferramenta de métricas do procesador. O principal é que a máquina virtual está en Linux. Por algunha razón Windows non proporciona esta información aos seus usuarios. 🙁

Roubar: quen rouba o tempo do procesador das máquinas virtuais
Saída do comando superior: detalles da carga do procesador, na columna máis á dereita - roubar

A dificultade xorde ao intentar obter esta información do hipervisor. Podes tentar predicir o roubo na máquina host, por exemplo, usando o parámetro Load Average (LA), o valor medio do número de procesos que agardan na cola de execución. O método para calcular este parámetro non é sinxelo, pero en xeral, se o LA normalizado polo número de fíos do procesador é superior a 1, isto indica que o servidor Linux está sobrecargado con algo.

A que están esperando todos estes procesos? A resposta obvia é o procesador. Pero a resposta non é do todo correcta, porque ás veces o procesador é gratuíto, pero LA vai fóra de escala. Lembra como cae NFS e como medra LA. O mesmo pode ocorrer cun disco e outros dispositivos de entrada/saída. Pero de feito, os procesos poden esperar ao final de calquera bloqueo, xa sexa físico, asociado a un dispositivo de E/S ou lóxico, como un mutex. Isto tamén inclúe o bloqueo a nivel de hardware (a mesma resposta do disco) ou lóxico (as chamadas primitivas de bloqueo, que inclúen unha morea de entidades, mutex adaptativo e spin, semáforos, variables de condición, bloqueos rw, bloqueos ipc). ...).

Outra característica de LA é que se considera como un sistema operativo medio. Por exemplo, 100 procesos compiten por un ficheiro e despois LA=50. Un valor tan grande parece indicar que o sistema operativo é malo. Pero para outro código escrito mal, este pode ser un estado normal, a pesar de que só é malo, e outros procesos do sistema operativo non sofren.

Debido a esta media (e en nada menos que nun minuto), determinar nada polo indicador LA non é a tarefa máis gratificante, con resultados moi incertos en casos concretos. Se intentas descubrilo, descubrirás que os artigos da Wikipedia e outros recursos dispoñibles describen só os casos máis sinxelos, sen unha explicación profunda do proceso. Envio de novo a todos os que estean interesados, aquí para Brendan Gregg  - siga as ligazóns a continuación. Quen é demasiado preguiceiro para falar inglés - tradución do seu popular artigo sobre LA.

3. Efectos especiais

Agora vexamos os principais casos de roubo que atopamos. Vouche dicir como seguen todo o anterior e como se relacionan cos indicadores do hipervisor.

Reciclaxe. O máis sinxelo e habitual: reutilizouse o hipervisor. De feito, hai moitas máquinas virtuais en execución, alto consumo de procesador no seu interior, moita competencia, a utilización de LA é superior a 1 (normalizada por fíos do procesador). Todo o que hai dentro de todas as máquinas virtuais diminúe. O roubo transmitido desde o hipervisor tamén está crecendo, é necesario redistribuír a carga ou apagar alguén. En xeral, todo é lóxico e comprensible.

Paravirtualización vs. instancias individuais. Só hai unha máquina virtual no hipervisor; consome unha pequena parte dela, pero produce unha gran carga de E/S, por exemplo no disco. E desde algún lugar aparece nel un pequeno roubo, ata o 10% (como mostran varios experimentos).

O caso é interesante. Steal aparece aquí precisamente polo bloqueo a nivel de controladores paravirtualizados. Créase unha interrupción dentro da máquina virtual, procesada polo controlador e enviada ao hipervisor. Debido ao manexo de interrupcións no hipervisor, para a máquina virtual parece unha solicitude enviada, está lista para a súa execución e está á espera do procesador, pero non se lle dá tempo de procesador. A rapaza virtual pensa que esta vez foi roubada.

Isto ocorre no momento en que se envía o búfer, vai ao espazo do núcleo do hipervisor e comezamos a esperalo. Aínda que, desde o punto de vista da máquina virtual, debería volver inmediatamente. Polo tanto, segundo o algoritmo de cálculo do roubo, esta vez considérase roubado. O máis probable é que nesta situación poida haber outros mecanismos (por exemplo, procesar outras chamadas do sistema), pero non deberían ser moi diferentes.

Programador fronte a máquinas virtuais altamente cargadas. Cando unha máquina virtual sofre roubo máis que outras, isto débese ao programador. Canto máis cargue un proceso o procesador, máis cedo o programador o expulsará para que os demais tamén poidan funcionar. Se a máquina virtual consome pouco, dificilmente verá roubo: o seu proceso sinceramente sentou e agardou, hai que darlle máis tempo. Se unha máquina virtual produce a máxima carga en todos os seus núcleos, moitas veces é expulsada do procesador e intentan non darlle moito tempo.

É aínda peor cando os procesos dentro da máquina virtual tentan obter máis procesador porque non poden facer fronte ao procesamento de datos. Entón, o sistema operativo do hipervisor, debido á optimización honesta, proporcionará cada vez menos tempo de procesador. Este proceso prodúcese como unha avalancha, e roubo saltos ao ceo, aínda que outras máquinas virtuais case non se decatarán. E cantos máis núcleos, peor será a máquina afectada. En resumo, as máquinas virtuais moi cargadas e con moitos núcleos sofren máis.

Baixo LA, pero hai roubo. Se LA é de aproximadamente 0,7 (é dicir, o hipervisor parece estar subcargado), pero obsérvase roubo dentro das máquinas virtuais individuais:

  • A opción con paravirtualización xa descrita anteriormente. A máquina virtual pode recibir métricas que indiquen roubo, aínda que o hipervisor está ben. Segundo os resultados dos nosos experimentos, esta opción de roubo non supera o 10% e non debería ter un impacto significativo no rendemento das aplicacións dentro da máquina virtual.
  • O parámetro LA está calculado incorrectamente. Máis precisamente, en cada momento concreto calcúlase correctamente, pero cando se fai unha media dun minuto resulta infravalorado. Por exemplo, se unha máquina virtual por terzo do hipervisor consome todos os seus procesadores durante exactamente medio minuto, entón LA por minuto no hipervisor será de 0,15; catro máquinas virtuais deste tipo que traballan simultaneamente darán 0,6. E o feito de que durante medio minuto en cada un deles houbo un roubo salvaxe ao 25% segundo o indicador LA xa non se pode sacar.
  • De novo, por mor do programador que decidiu que alguén estaba comendo demasiado e deixou que ese alguén esperase. Mentres tanto, cambiarei o contexto, xestionarei interrupcións e encargarei outras cousas importantes do sistema. Como resultado, algunhas máquinas virtuais non ven ningún problema, mentres que outras experimentan unha grave degradación do rendemento.

4. Outras distorsións

Hai un millón de razóns máis para distorsionar o retorno xusto do tempo do procesador nunha máquina virtual. Por exemplo, hyperthreading e NUMA introducen dificultades nos cálculos. Confunden completamente a elección do núcleo para executar o proceso, porque o planificador usa coeficientes - pesos, que dificultan aínda máis o cálculo ao cambiar o contexto.

Existen distorsións debidas a tecnoloxías como o turbo boost ou, pola contra, o modo de aforro de enerxía que, ao calcular a utilización, poden aumentar ou diminuír artificialmente a frecuencia ou mesmo o intervalo de tempo no servidor. A activación do turbo boost reduce o rendemento dun fío do procesador debido ao aumento do rendemento doutro. Neste momento, a información sobre a frecuencia do procesador actual non se transmite á máquina virtual e cre que alguén lle está a roubar o tempo (por exemplo, solicitou 2 GHz, pero recibiu a metade).

En xeral, pode haber moitas razóns para a distorsión. Podes atopar algo máis nun sistema en particular. É mellor comezar cos libros aos que dei ligazóns arriba, e recuperando estatísticas do hipervisor usando utilidades como perf, sysdig, systemtap, das cales ducias.

5. Conclusións

  1. Pode producirse algunha cantidade de roubo debido á paravirtualización e pódese considerar normal. Eles escriben en Internet que este valor pode ser 5-10%. Depende das aplicacións dentro da máquina virtual e da carga que lle supoña aos seus dispositivos físicos. Aquí é importante prestar atención a como se senten as aplicacións dentro das máquinas virtuais.
  2. A relación entre a carga no hipervisor e o roubo dentro da máquina virtual non sempre están claramente interrelacionadas; ambas as estimacións de roubo poden ser erróneas en situacións específicas baixo diferentes cargas.
  3. O planificador ten unha mala actitude ante os procesos que piden moito. Tenta dar menos a quen pide máis. As grandes máquinas virtuais son malas.
  4. Un pequeno roubo pode ser a norma mesmo sen paravirtualización (tendo en conta a carga dentro da máquina virtual, as características da carga dos veciños, a distribución da carga entre fíos e outros factores).
  5. Se queres descubrir o roubo nun sistema específico, tes que explorar varias opcións, recoller métricas, analizalas coidadosamente e pensar en como distribuír uniformemente a carga. Son posibles desviacións de calquera caso, que deben ser confirmados experimentalmente ou examinados no depurador do núcleo.

Fonte: www.habr.com

Engadir un comentario