RAID Revisitado
Quando eu era um técnico de assistência principiante e mal sabia alguma coisa sobre administração de sistemas, um dos poucos temas que se esperava sempre que dominássemos a fundo era o RAID – Redundant Array of Inexpensive Disks. Era a resposta para todos os nossos problemas de armazenamento. Com o RAID podíamos dimensionar os nossos sistemas de ficheiros para maiores, obter melhor débito e até acrescentar redundância, permitindo-nos sobreviver à perda de um disco que, especialmente naqueles tempos, acontecia com bastante regularidade. Com a ascensão dos appliances de armazenamento NAS e SAN, o conjunto de competências para descer ao nível físico do armazenamento e ajustá-lo para satisfazer as necessidades do sistema em questão está a desaparecer rapidamente. Isto não é uma coisa boa. O facto de estarmos a transferir o armazenamento para dispositivos externos não altera o facto de que precisamos de compreender fundamentalmente o nosso armazenamento e configurá-lo para satisfazer as necessidades específicas dos nossos sistemas.
Um equívoco que parece ter entrado no campo ao longo dos últimos cinco a dez anos é a crença de que o RAID representa de alguma forma um backup do sistema. Não representa. O RAID é uma forma de tolerância a falhas. Backup e tolerância a falhas são conceitualmente muito diferentes. O backup é concebido para lhe permitir recuperar depois de ter ocorrido um desastre. A tolerância a falhas é concebida para diminuir, antes de mais, a probabilidade de desastre. Pense na tolerância a falhas como a construção de uma vedação no topo de um penhasco e no backup como a construção de um hospital na base dele. Nunca quererá realmente estar numa situação sem ter tanto uma vedação como um hospital, mas são definitivamente coisas diferentes.
Uma vez que estamos a implementar RAID para os nossos discos, quer estejam ligados localmente quer num appliance remoto como o SAN, temos hoje quatro soluções RAID fundamentais à escolha para empresas: RAID 1 (espelhamento), RAID 5 (striping com paridade), RAID 6 (striping com paridade dupla) e RAID 10 (espelhamento com striping). Existem outras, como o RAID 0, que só deveriam ser utilizadas em circunstâncias raras, quando se compreende realmente as necessidades do subsistema de discos. O RAID 50 e o 51 também são utilizados, mas muito menos comummente e não são nem de longe tão eficazes. Há dez anos, o RAID 1 e o RAID 5 eram comuns, mas hoje temos mais opções.
Vamos analisar passo a passo as opções e discutir alguns números básicos. Nos nossos exemplos utilizaremos n para representar o número de discos no nosso array e utilizaremos s para representar a dimensão de qualquer disco individual. Usando estes, podemos exprimir o espaço de armazenamento utilizável de um array, tornando fáceis as comparações em termos de capacidade de armazenamento.
RAID 1: Neste tipo de RAID os discos são espelhados. Tem dois discos e eles fazem tudo em conjunto ao mesmo tempo, daí o “espelhamento”. O espelhamento é extremamente estável, pois o processo é muito simples, mas exige que adquira o dobro dos discos que necessitaria se não estivesse a utilizar RAID de todo, uma vez que o seu segundo disco é dedicado à redundância. O benefício é que tem a garantia de que cada bit que escreve em disco está a ser escrito duas vezes para sua proteção. Assim, com o RAID 1 a nossa capacidade é calculada como (n*s/2). O RAID 1 sofre de proporcionar ganhos de desempenho mínimos face a discos sem RAID. As velocidades de escrita são equivalentes às de um sistema sem RAID, enquanto as velocidades de leitura são quase duas vezes mais rápidas na maioria das situações, uma vez que durante as operações de leitura os discos podem ser acedidos em paralelo para aumentar o débito. O RAID 1 está limitado a conjuntos de dois discos.
RAID 5: Striping com Paridade Única; neste tipo de RAID os dados são escritos numa faixa (stripe) complexa ao longo de todos os discos do array, com um bloco de paridade distribuído que existe ao longo de todos os discos. Ao fazer isto, o RAID 5 consegue utilizar um array de dimensão arbitrária de três ou mais discos e perde apenas a capacidade de armazenamento equivalente a um único disco para a paridade, embora a paridade seja distribuída e não exista exclusivamente em nenhum disco físico individual. O RAID 5 é frequentemente utilizado devido à sua relação custo-eficácia, em virtude da sua reduzida perda de capacidade de armazenamento em arrays grandes. Ao contrário do espelhamento, o striping com paridade exige que seja efetuado um cálculo para cada faixa de escrita ao longo dos discos, e isto gera alguma sobrecarga. Por conseguinte, o débito nem sempre é um cálculo óbvio e depende fortemente da capacidade computacional do sistema que efetua o cálculo de paridade. Calcular a capacidade do RAID 5 é bastante fácil, pois é simplesmente ((n-1)*s). Um array RAID 5 pode sobreviver à perda de qualquer disco individual do array.
RAID 6: Striping Redundante com Paridade Dupla. O RAID 6 é praticamente idêntico ao RAID 5, mas utiliza dois blocos de paridade por faixa em vez de um, para permitir proteção adicional contra falhas de disco. O RAID 6 é um membro mais recente da família RAID, tendo sido acrescentado vários anos depois de os outros níveis se terem tornado padronizados. O RAID 6 é especial porque permite a falha de quaisquer dois discos dentro de um array sem sofrer perda de dados. Mas, para acomodar o nível adicional de redundância, um array RAID 6 perde a capacidade de armazenamento equivalente a dois discos no array e requer um mínimo de quatro discos. Podemos calcular a capacidade de um array RAID 6 com ((n-2)*s).
RAID 10: Espelhamento mais Striping. Tecnicamente, o RAID 10 é um tipo de RAID híbrido que engloba um conjunto de espelhos RAID 1 existentes numa faixa sem paridade (RAID 0). Muitos fornecedores utilizam o termo RAID 10 (ou RAID 1+0) ao referirem-se apenas a dois discos num array, mas tecnicamente isso é RAID 1, uma vez que o striping não pode ocorrer enquanto não houver um mínimo de quatro discos no array. Com o RAID 10, os discos têm de ser acrescentados em pares, pelo que só pode existir um número par de discos num array. O RAID 10 pode sobreviver à perda de até metade do conjunto total de discos, mas com uma perda máxima de um disco de cada par. O RAID 10 não envolve um cálculo de paridade, conferindo-lhe uma vantagem de desempenho face ao RAID 5 ou ao RAID 6 e exigindo menos capacidade computacional para gerir o array. O RAID 10 entrega o maior desempenho de leitura de qualquer tipo comum de RAID, uma vez que todos os discos do array podem ser utilizados simultaneamente em operações de leitura, embora o seu desempenho de escrita seja muito inferior. O cálculo de capacidade do RAID 10 é idêntico ao do RAID 1, (n*s/2).
Na empresa de hoje, é raro um departamento de TI ter uma necessidade séria de considerar qualquer configuração de discos para além das quatro aqui mencionadas, independentemente de estar a ser implementado RAID por software ou por hardware. Tradicionalmente, a maior preocupação numa decisão de array RAID baseava-se na capacidade utilizável. Isto devia-se ao facto de os discos serem dispendiosos e pequenos. Hoje, os discos são tão grandes que a capacidade de armazenamento raramente é um problema, pelo menos não como era há apenas alguns anos, e os custos baixaram de tal forma que a aquisição dos discos adicionais necessários para uma melhor redundância de discos é geralmente de menor preocupação. Quando a capacidade é escassa, o RAID 5 é uma escolha popular porque perde a menor capacidade de armazenamento em comparação com outros tipos de array e, em arrays grandes, a perda de armazenamento é simbólica.
Hoje temos geralmente outras preocupações, principalmente a segurança dos dados e o desempenho. Gastar um pouco mais para garantir a proteção dos dados deveria ser uma escolha óbvia. O RAID 5 sofre de só conseguir perder um único disco. Num array de apenas três membros, isto é apenas ligeiramente mais perigoso do que a proteção oferecida pelo RAID 1. Poderíamos sobreviver à perda de qualquer um de três discos. Não muito assustador em comparação com perder qualquer um de dois discos. Mas e quanto a um array grande, digamos dezasseis discos. Conseguir perder com segurança apenas um de dezasseis discos deveria levar-nos a questionar a nossa fiabilidade um pouco mais a fundo.
Foi aqui que o RAID 6 entrou para preencher a lacuna. O RAID 6, quando utilizado num array grande, introduz uma perda muito pequena de capacidade de armazenamento e de desempenho, ao mesmo tempo que proporciona a garantia de se poder perder quaisquer dois discos. Os defensores do campo do striping com paridade citarão frequentemente estes números para tranquilizar a gestão de que o RAID 5/6 pode proporcionar uma adequada relação custo-benefício nos subsistemas de armazenamento, mas há outros fatores em jogo.
Quase inteiramente ignorada nas discussões sobre fiabilidade do RAID, um tema discutido demasiado raramente como é, está a questão da fiabilidade do cálculo de paridade. Com o RAID 1 ou o RAID 10 não há qualquer “cálculo” efetuado para criar uma faixa com paridade. Os dados são simplesmente escritos de forma estável. Quando um disco falha, o seu parceiro assume a carga e o desempenho do disco fica ligeiramente degradado até que o parceiro seja substituído. Não há qualquer processo de reconstrução que afete os membros de disco existentes. Não é assim com as faixas de paridade.
Os arrays RAID com paridade têm operações que envolvem calcular o que está e o que deveria estar nos discos. Embora este cálculo seja muito simples, proporciona uma oportunidade para as coisas correrem mal. Um controlador de array que falhe com RAID 1 ou RAID 10 poderia, em teoria, escrever dados incorretos por cima do conteúdo dos discos, mas não há qualquer processo pelo qual o controlador efetue alterações nos discos por si próprio, pelo que é extremamente improvável que isto alguma vez ocorra, uma vez que nunca há um processo de “reconstrução” exceto ao criar um espelho.
Quando os arrays com paridade efetuam uma operação de reconstrução, executam um processo complexo pelo qual percorrem todo o conteúdo do array e escrevem os dados em falta de volta para o disco substituído. Em si mesmo, isto é relativamente simples e não deveria ser motivo de preocupação. O que eu e outros vimos em primeira mão é um cenário ligeiramente diferente, envolvendo discos que perderam conectividade devido a conectores soltos no array. Os discos podem comummente “abanar” e soltar-se com o tempo enquanto estão num servidor, especialmente após vários anos de serviço num sistema sempre ligado.
O que pode acontecer, em cenários extremos, é que bons dados nos discos podem ser sobrescritos por dados de paridade incorretos quando um controlador de array acredita que um ou mais discos falharam em sucessão e foram colocados novamente online para reconstrução. Neste caso, os próprios discos não falharam e não há perda de dados. Tudo o que é necessário é que os discos sejam reencaixados, em teoria. Em sistemas hot swap, a gestão da reconstrução de discos é frequentemente automática, baseada na remoção e substituição de um disco com falha. Assim, este processo de perder e substituir um disco pode ocorrer sem qualquer intervenção humana – e um processo de reconstrução pode iniciar-se. Durante este processo, o sistema de discos está em risco e, caso este mesmo evento ocorra novamente, o array de discos pode, com base no estado dos discos, começar a fazer striping de dados incorretos ao longo dos discos, sobrescrevendo o bom sistema de ficheiros. É uma das visões mais deprimentes para um administrador de servidores, ver um sistema sem discos falhados perder um array inteiro devido a uma operação de reconstrução desnecessária.
Em teoria, este tipo de situação não deveria ocorrer e existem salvaguardas para proteger contra ela, mas a determinação por parte de um controlador de discos de baixo nível quanto ao estado de um disco no presente e no passado e quanto à qualidade dos dados que nele residem não é tão simples como pode parecer e é possível que ocorram erros. Embora esta situação seja improvável, ela acontece e acrescenta um risco quase impossível de calcular aos sistemas RAID 5 e RAID 6. Temos de considerar o risco de falha de paridade para além do risco tradicional calculado a partir do número de perdas de disco que um array pode sobreviver de entre um conjunto. À medida que os discos se tornam mais fiáveis, a significância do evento de risco de falha de paridade torna-se maior.
Adicionalmente, a paridade do RAID 5 e do RAID 6 introduz sobrecarga no sistema devido ao cálculo de paridade, que é frequentemente tratado através de hardware RAID dedicado. Este cálculo introduz latência no subsistema de discos que varia dramaticamente consoante a implementação, tanto em hardware como em software, tornando impossível afirmar números de desempenho dos níveis RAID uns em relação aos outros, uma vez que cada implementação será única.
Possivelmente o maior problema com as escolhas de RAID atualmente é que a facilidade com que se podem obter métricas para a eficiência de armazenamento e a sobrevivência à perda de discos mascara o quadro geral de fiabilidade e desempenho, uma vez que essas estatísticas estão quase inteiramente indisponíveis. Um dos perigos das métricas é que as pessoas se concentram em fatores que podem ser facilmente medidos e ignoram aqueles que não podem ser facilmente medidos, independentemente do seu potencial impacto.
Embora todos os níveis modernos de RAID tenham o seu lugar, é fundamental que sejam considerados dentro do contexto e com uma compreensão de todo o âmbito dos riscos. Devemos esforçar-nos por mudar a nossa indústria de um padrão de RAID 5 para um padrão de RAID 10. Os discos são baratos e a perda de dados é dispendiosa.
[Edição: Nos anos decorridos desde que isto foi inicialmente escrito, a ascensão dos riscos de URE (Unrecoverable Read Errors) durante uma operação de reconstrução deslocou os principais riscos dos aqui listados para os riscos relacionados com URE nos arrays de paridade.]
