Discos de SO Lentos, Discos de Dados Rápidos
Ao longo dos anos, descobri que as pessoas frequentemente erram pelo lado do armazenamento de alto desempenho e alta confiabilidade para uma partição de sistema operacional, mas escolhem um armazenamento lento e “econômico” para repositórios de dados críticos. Fico espantado com a frequência com que encontro isso ocorrendo e agora, com o advento dos hypervisores, vejo o mesmo comportamento sendo repetido ali também – agravando os problemas que já existiam.
Em muitos sistemas hoje, lidamos com apenas um único array de armazenamento compartilhado por todos os componentes do sistema. Nesses casos, não enfrentamos o problema de desequilibrar o desempenho de nosso sistema de armazenamento. Esta é uma das grandes vantagens dessa abordagem e uma das principais razões pelas quais ela é tão altamente recomendada. Todo o desempenho está em um pool compartilhado e os componentes que precisam do desempenho têm acesso a ele.
Em muitos casos, seja em uma tentativa de aumento de desempenho ou de design de confiabilidade, seja por necessidade técnica, descubro que as pessoas estão separando seus arrays de armazenamento e colocando os hypervisores e sistemas operacionais em um array e os dados em outro. Mas o que acho chocante é que os arrays dedicados ao hypervisor ou ao sistema operacional são frequentemente surpreendentemente grandes em capacidade e extremamente altos em desempenho – muitas vezes envolvendo discos de 15.000 RPM ou até mesmo discos de estado sólido a grande custo. Quase sempre em RAID 1 (conforme os padrões comuns de 1998).
O que precisa ser compreendido aqui é que os próprios sistemas operacionais não têm, efetivamente, nenhum requisito de IO de armazenamento. Há uma pequena quantidade, principalmente para o registro de log do sistema, mas isso é praticamente tudo o que é necessário. As partições de sistema operacional são quase completamente estáticas. Os componentes necessários são carregados na memória, principalmente no momento da inicialização, e não são acessados novamente. Mesmo nos casos em que o registro de log é necessário, muitas vezes esses logs são enviados para um sistema de log centralizado e não para a área de armazenamento do sistema, reduzindo ou até mesmo eliminando essa necessidade também.
Com os hypervisores, esse efeito é ainda mais extremo. Como os hypervisores são muito mais leves e menos robustos do que os sistemas operacionais tradicionais, eles se comportam mais como sistemas embarcados e, de muitas maneiras, na verdade são sistemas embarcados em muitos casos. Os hypervisores são carregados na memória no momento da inicialização do sistema e sua mídia quase nunca é necessária novamente enquanto um sistema está em execução, exceto para o registro de log em algumas ocasiões. Como os hypervisores são pequenos em tamanho físico, mesmo o tempo total necessário para ler completamente um hypervisor inteiro a partir do armazenamento é muito pequeno, mesmo em mídia muito lenta, porque o tamanho total é muito pequeno.
Por essas razões, o desempenho de armazenamento é de pouca ou nenhuma consequência para os sistemas operacionais e, especialmente, para os hypervisores. A diferença entre armazenamento rápido e armazenamento lento realmente só impacta o tempo de inicialização do sistema, onde a diferença de um segundo ou trinta segundos raramente seria notada, se é que seria. Quando alguém perceberia até mesmo vários segundos a mais durante a inicialização de um sistema e, na maioria dos casos, as inicializações são eventos raros, acontecendo no máximo uma vez por semana durante uma reinicialização rotineira e automatizada do sistema em uma janela de manutenção planejada ou, muito raramente, às vezes apenas uma vez a cada vários anos, para sistemas que só são colocados offline em emergências. Mesmo o sistema de armazenamento mais lento concebível é muito mais rápido do que o necessário para esse papel.
Mesmo o armazenamento lento é geralmente muitas vezes mais rápido do que o necessário para as atividades de registro de log do sistema. Naqueles raros casos em que o registro de log é muito intenso, temos muitas escolhas de como abordar esse problema. A solução mais óbvia e comum aqui é enviar os logs para um array de discos diferente daquele usado pelo sistema operacional ou hypervisor. Esta é uma solução muito fácil e, em última análise, muito prática nos casos em que se justifica. A outra solução comum e altamente útil é simplesmente abster-se de manter os logs no dispositivo local e enviá-los para um utilitário remoto de coleta de logs, como Splunk, Loggly ou ELK.
A outra grande preocupação que a maioria das pessoas tem em relação aos seus sistemas operacionais e hypervisores é a confiabilidade. É comum concentrar mais esforços na proteção desses aspectos relativamente sem importância de um sistema do que nos dados, muitas vezes insubstituíveis. No entanto, os sistemas operacionais e os hypervisores são facilmente reconstruídos do zero quando necessário, usando instalações novas e reconfiguração manual quando necessário. Os detalhes que poderiam ser perdidos são geralmente relativamente triviais de recriar.
Isto não significa que os sistemas de arquivos desses sistemas não devam ser copiados em backup; é claro que devem (na maioria dos casos). Mas, no caso de os backups também falharem, é raro que a perda de uma partição ou sistema de arquivos de SO realmente signifique uma tragédia, mas apenas um inconveniente. Há maneiras de recuperar em quase todos os casos sem acesso aos dados originais, desde que o sistema de arquivos de “dados” seja separado. E, por causa da natureza dos sistemas operacionais e hypervisores, a mudança é rara, de modo que os backups podem geralmente ser menos frequentes, possivelmente acionados manualmente apenas quando as atualizações são aplicadas!
Com muitos sistemas modernos nos espaços de DevOps e computação em nuvem, tornou-se muito comum encarar os sistemas de arquivos de sistemas operacionais e hypervisores como completamente descartáveis, já que são definidos remotamente por meio de uma imagem de sistema ou por um sistema de gerenciamento de configuração. Nesses casos, que estão se tornando cada vez mais comuns, não há necessidade de proteção de dados ou backups, pois todo o sistema é projetado para ser recriado, quase instantaneamente, sem qualquer interação especial. O sistema é inteiramente autorreplicante. Isto trivializa ainda mais a necessidade de proteção do sistema de arquivos do sistema.
Considerados em conjunto, a falta de necessidade em torno do desempenho e a falta de necessidade em torno da proteção e da confiabilidade, tratadas principalmente por meio da simples recriação, e o que temos é um sistema de arquivos de sistema com necessidades muito diferentes do que comumente presumimos. Isto não significa que devamos ser imprudentes com nosso armazenamento; ainda queremos evitar a falha de armazenamento enquanto um sistema está em execução, e reconstruir desnecessariamente é um desperdício de tempo e recursos, mesmo que não se mostre desastroso. Portanto, encontrar um equilíbrio cuidadoso é importante.
É, claro, por essas razões que incluir o sistema operacional ou o hypervisor no mesmo array de armazenamento que os dados é agora uma prática comum – porque há pouca ou nenhuma necessidade de acesso de armazenamento aos arquivos do sistema ao mesmo tempo em que há acesso aos arquivos de dados, de modo que obtemos uma grande sinergia ao conseguir tempos de inicialização rápidos para o SO e nenhum impacto adverso nos tempos de acesso aos dados uma vez que o sistema esteja online. Este é o principal meio pelo qual os projetistas de sistemas hoje abordam a necessidade de uso eficiente do armazenamento.
Quando o sistema operacional ou o hypervisor deve ser separado dos arrays que contêm os dados, o que ainda pode acontecer por inúmeras razões, geralmente buscamos obter uma confiabilidade razoável a baixo custo. Ao usar armazenamento tradicional (discos locais), isso significa usar discos giratórios pequenos, lentos e de baixo custo para o armazenamento do sistema operacional, geralmente em uma configuração RAID 1 simples. Um exemplo do mundo real é o uso de discos SATA de 5400 RPM “ecologicamente corretos” nos menores tamanhos possíveis. Eles consomem pouca energia e são muito baratos de adquirir. SSDs e discos SAS de alta velocidade seriam evitados, pois custam um valor adicional por uma proteção que é irrelevante e um desempenho que é completamente desperdiçado.
Em armazenamento menos tradicional, é comum usar uma SAN de baixo custo e alta densidade, consolidando o armazenamento de baixa prioridade de muitos sistemas em arrays compartilhados e lentos que não são replicados. Isto só é eficaz em ambientes maiores que possam justificar o design arquitetônico adicional e que possam alcançar densidade suficiente no processo de consolidação de armazenamento para criar a economia de custos necessária, mas em ambientes maiores isso é relativamente fácil. Dispositivos de inicialização (boot) SAN podem aproveitar arrays de custo muito baixo em muitos servidores para economia de custos. No espaço virtual, isso poderia significar um datastore de baixo desempenho usado para os discos virtuais do SO e outro pool, de alto desempenho, para os discos virtuais de dados. Isto teria o mesmo efeito que a estratégia de SAN de boot, mas em um cenário mais moderno e poderia facilmente aproveitar a arquitetura SAN nos bastidores para realizá-lo.
Por fim, e de forma mais drástica, é uma regra prática geral com os hypervisores instalá-los em cartões SD ou pen drives USB em vez de armazenamento tradicional, já que suas necessidades de desempenho e confiabilidade são muito menores até mesmo do que as dos sistemas operacionais tradicionais. Normalmente, se um disco dessa natureza falhasse enquanto um sistema estivesse em execução, ele na verdade permaneceria em execução sem qualquer problema, pois o disco nunca é usado uma vez que o sistema tenha inicializado inicialmente. Seria apenas durante uma reinicialização que um problema seria encontrado e, nesse momento, um dispositivo de inicialização de backup poderia ser usado, como um cartão SD ou pen drive USB secundário. Esta é a recomendação oficial para o VMware vSphere, é frequentemente recomendada por representantes da Microsoft para o HyperV e é oficialmente suportada por meio dos fornecedores OEM do HyperV, e é frequentemente recomendada, mas não tão amplamente suportada, para sistemas Xen, XenServer e KVM. Usar cartões SD ou drives USB para o armazenamento do hypervisor efetivamente transforma um servidor de virtualização em um sistema embarcado. Embora isso possa parecer antinatural para administradores de sistemas acostumados a pensar nos discos tradicionais como uma necessidade para servidores, é importante lembrar que sistemas de classe corporativa e altamente críticos, como roteadores e switches, duram décadas e usam exatamente essa mesma estratégia pelas exatas mesmas razões.
Uma estratégia comum para hypervisores nesse modo de estilo embarcado com cartões SD ou drives USB é ter dois desses dispositivos, que podem na verdade ser um cartão SD e um drive USB, cada um com uma cópia do hypervisor. Se um dispositivo falhar, inicializar a partir do segundo dispositivo é quase tão eficaz quanto um sistema RAID 1 tradicional. Mas, diferentemente da maioria das configurações tradicionais de RAID 1, também temos um meio relativamente fácil de testar atualizações do sistema, atualizando apenas um dispositivo de inicialização de cada vez e testando o processo antes de atualizar o segundo dispositivo de inicialização, deixando-nos com um recurso de retorno confiável e bem testado caso uma atualização de versão dê errado. Esse processo era na verdade comum em grandes sistemas UNIX RISC, onde os dispositivos de inicialização eram frequentemente conjuntos de RAID 1 por software local que suportavam uma prática semelhante, especialmente comum nos círculos de AIX e Solaris.
Deve-se também notar que, embora essa abordagem seja a melhor prática para a maioria dos cenários de hypervisor, não há na verdade nenhuma razão pela qual ela não possa ser aplicada também a sistemas de arquivos de sistema operacional completos, exceto que muitas vezes dá mais trabalho. Alguns SOs, especialmente Linux e BSD, são muito hábeis em serem instalados de forma embarcada e podem ser facilmente adaptados para instalação em cartão SD ou drive USB com um pouco de planejamento. Esta abordagem não é nem um pouco comum, mas não há nenhuma razão técnica pela qual, nas circunstâncias certas, ela não seria uma excelente abordagem, exceto pelo fato de que quase nunca um SO deveria ser instalado em hardware físico em vez de sobre um hypervisor. Naqueles casos em que as instalações físicas são necessárias, então esta abordagem é extremamente válida.
Ao projetar e planejar sistemas de armazenamento, lembre-se de estar atento a como os padrões de leitura e escrita realmente serão quando um sistema estiver em execução. E lembre-se de que o armazenamento mudou de forma bastante drástica desde que muitas diretrizes tradicionais foram desenvolvidas e nem todo o conhecimento usado para desenvolvê-las ainda se aplica hoje ou se aplica de forma igual. Pense não apenas em quais subsistemas de armazenamento tentarão usar o desempenho de armazenamento, mas também em como eles interagirão entre si (por exemplo, dois sistemas nunca solicitam acesso ao armazenamento ao mesmo tempo ou eles entrarão em conflito regularmente?) e se o desempenho de acesso deles é importante ou não. As funções gerais do sistema operacional podem ser extremamente lentas em um servidor de banco de dados sem impacto negativo; tudo o que importa é a velocidade com que um banco de dados pode ser acessado. Mesmo o acesso aos binários dos aplicativos é frequentemente irrelevante, pois eles também, uma vez carregados na memória, ali permanecem e somente a velocidade da memória impacta o desempenho contínuo.
Nada disso pretende sugerir que separar os subsistemas de armazenamento de SO e de dados um do outro seja aconselhável; frequentemente não é. Escrevi no passado sobre como consolidar esses subsistemas é, com bastante frequência, o melhor curso de ação, e isso permanece verdadeiro agora. Mas também há muitos casos razoáveis em que faz sentido separar certas necessidades de armazenamento umas das outras, muitas vezes ao lidar com sistemas de grande escala, onde podemos reduzir custos dedicando armazenamento de alto custo a certas necessidades e armazenamento de baixo custo a outras necessidades, e é nesses casos que quero demonstrar que os sistemas operacionais e hypervisores devem ser considerados a mais baixa prioridade em termos tanto de desempenho quanto de confiabilidade, exceto nos casos mais extremos.
