A alta disponibilidade é um dos principais requisitos em aplicativos de negócios sérios e o armazenamento altamente disponível é um componente-chave nesses ambientes. No FreeBSD, o framework Alta Disponiblidade de Armazenamento (HAST) permite o armazenamento transparente dos mesmos dados em várias máquinas fisicamente separadas conectadas por uma rede TCP/IP. HAST pode ser entendido como um RAID1 (mirror) baseado em rede, e é similar ao sistema de armazenamento DRBD® usado na plataforma GNU/Linux®. Em combinação com outros recursos de alta disponibilidade do FreeBSD, como o CARP, o HAST possibilita a criação de um cluster de armazenamento altamente disponível, resistente a falhas de hardware.
A seguir estão as principais características do HAST:
Pode ser usado para mascarar erros de I/O em discos rígidos locais.
Agnóstico a sistema de arquivos, pois funciona com qualquer sistema de arquivos suportado pelo FreeBSD.
Ressincronização eficiente e rápida, pois somente os blocos que foram modificados durante o tempo de inatividade de um nó são sincronizados.
Pode ser usado em um ambiente já implantado para adicionar redundância adicional.
Juntamente com o CARP, Heartbeat, ou outras ferramentas, ele pode ser usado para construir um sistema de armazenamento robusto e durável.
Depois de ler esta seção, você saberá:
O que é HAST, como ele funciona e quais recursos ele fornece.
Como configurar e usar o HAST no FreeBSD.
Como integrar CARP e devd(8) para criar um sistema de armazenamento robusto.
Antes de ler esta seção, você deve:
Entender os fundamentos do UNIX® e do FreeBSD (Capítulo 3, Fundamentos do FreeBSD).
Saber como configurar interfaces de rede e outros subsistemas principais do FreeBSD (Capítulo 11, Configuração e Ajuste).
Ter uma boa compreensão da rede do FreeBSD (Parte IV, “Comunicação de rede”).
O projeto HAST foi patrocinado pela Fundação FreeBSD com o apoio de http://www.omc.net/ e http://www.transip.nl/.
O HAST fornece replicação síncrona em nível de bloco entre duas máquinas físicas: o primário, também conhecido como o nó master, e o secundário, ou nó slave. Essas duas máquinas juntas são chamadas de cluster.
Como o HAST funciona em uma configuração primária-secundária, ele permite que apenas um dos nós do cluster esteja ativo a qualquer momento. O nó primário, também chamado de active, é aquele que irá lidar com todas as solicitações de I/O para dispositivos gerenciados por HAST. O nó secundário é automaticamente sincronizado a partir do nó primário.
Os componentes físicos do sistema HAST são o disco local no nó primário e o disco no nó secundário remoto.
O HAST opera de forma síncrona em um nível de bloco, tornando-o transparente para sistemas de arquivos e aplicativos. O HAST fornece provedores GEOM regulares em /dev/hast/
para uso por outras ferramentas ou aplicativos. Não há diferença entre o uso de dispositivos HAST e discos ou partições brutas.
Cada operação de gravação, exclusão ou liberação é enviada para o disco local e para o disco remoto sobre TCP/IP . Cada operação de leitura é fornecida a partir do disco local, a menos que o disco local não esteja atualizado ou ocorra um erro de I/O. Nesses casos, a operação de leitura é enviada para o nó secundário.
HAST tenta fornecer recuperação rápida de falhas. Por esse motivo, é importante reduzir o tempo de sincronização após a interrupção de um nó. Para fornecer sincronização rápida, o HAST gerencia um bitmap no disco de extensões sujas e sincroniza apenas aquelas durante uma sincronização regular, com exceção da sincronização inicial.
Existem muitas maneiras de lidar com a sincronização. O HAST implementa vários modos de replicação para lidar com diferentes métodos de sincronização:
memsync: Este modo reporta uma operação de gravação como concluída quando a operação de gravação local é finalizada e quando o nó remoto reconhece a chegada dos dados, mas antes de realmente armazenar os dados. Os dados no nó remoto serão armazenados diretamente após o envio da confirmação. Este modo destina-se a reduzir a latência, mas ainda fornece boa confiabilidade. Este modo é o padrão.
fullsync: Este modo relata uma operação de gravação como concluída quando a gravação local e a gravação remota são concluídas. Este é o modo de replicação mais seguro e mais lento.
async: Este modo relata uma operação de gravação como concluída quando a gravação local é concluída. Este é o modo de replicação mais rápido e mais perigoso. Ele deve ser usado somente ao replicar para um nó distante, onde a latência é muito alta para outros modos.
O framework HAST consiste em vários componentes:
O daemon hastd(8) que fornece sincronização de dados. Quando este daemon é iniciado, ele carregará automaticamente geom_gate.ko
.
O utilitário de gerenciamento de usuário, hastctl(8).
O arquivo de configuração hast.conf(5). Este arquivo deve existir antes de iniciar o hastd.
Usuários que preferem construir estaticamente o suporte a GEOM_GATE
no kernel devem adicionar esta linha ao arquivo de configuração do kernel personalizado e reconstruir o kernel usando as instruções em Capítulo 8, Configurando o kernel do FreeBSD:
options GEOM_GATE
O exemplo a seguir descreve como configurar dois nós na operação mestre-escravo/primário-secundário usando HAST para replicar os dados entre os dois. Os nós serão chamados hasta
, com um endereço IP 172.16.0.1
, e hastb
, com um endereço IP 172.16.0.2
. Ambos os nós terão um disco rígido dedicado /dev/ad6
do mesmo tamanho para a operação HAST. O conjunto HAST, por vezes referido como um recurso ou o provedor GEOM em /dev/hast/
, será chamado test
.
A configuração do HAST é feita usando o arquivo /etc/hast.conf
. Este arquivo deve ser idêntico nos dois nós. A configuração mais simples é:
resourcetest
{ onhasta
{ local/dev/ad6
remote172.16.0.2
} onhastb
{ local/dev/ad6
remote172.16.0.1
} }
Para uma configuração mais avançada, consulte hast.conf(5).
Também é possível usar nomes de host nas instruções remote
se os hosts forem resolvidos e definidos no arquivo /etc/hosts
ou no DNS local.
Uma vez que a configuração exista em ambos os nós, o conjunto HAST pode ser criado. Execute esses comandos nos dois nós para colocar os metadados iniciais no disco local e para iniciar hastd(8):
#
hastctl create
test
#
service hastd onestart
Não é possível usar os provedores GEOM com um sistema de arquivos existente ou converter um armazenamento existente em um pool gerenciado por HAST. Esse procedimento precisa armazenar alguns metadados no provedor e não haverá espaço suficiente disponível em um provedor existente.
Um nó HAST primário
ou secundário
é selecionado por um administrador, ou software como Heartbeat, usando hastctl(8). No nó primário, hasta
, execute este comando:
#
hastctl role primary
test
Execute este comando no nó secundário, hastb
:
#
hastctl role secondary
test
Verifique o resultado executando hastctl
em cada nó:
#
hastctl status
test
Verifique a linha status
na saída. Se disser degraded
, algo está errado com o arquivo de configuração. Ele deve dizer complete
em cada nó, o que significa que a sincronização entre os nós foi iniciada. A sincronização é concluída quando hastctl status
relata 0 bytes de extensões sujas
.
O próximo passo é criar um sistema de arquivos no provedor GEOM e montá-lo. Isso deve ser feito no nó primário
. A criação do sistema de arquivos pode levar alguns minutos, dependendo do tamanho do disco rígido. Este exemplo cria um sistema de arquivos UFS em /dev/hast/test
:
#
newfs -U /dev/hast/
test
#
mkdir /hast/
test
#
mount /dev/hast/
test
/hast/test
Uma vez que o framework HAST esteja configurado corretamente, o passo final é garantir que o HAST seja iniciado automaticamente durante a inicialização do sistema. Adicione esta linha ao /etc/rc.conf
:
hastd_enable="YES"
O objetivo deste exemplo é construir um sistema de armazenamento robusto que seja resistente à falha de qualquer nó. Se o nó primário falhar, o nó secundário estará lá para assumir o controle, verificar e montar o sistema de arquivos e continuar a trabalhar sem perder um único bit de dados.
Para realizar essa tarefa, o Protocolo de Redundância de Endereços Comuns (CARP) é usado para fornecer failover automático na camada IP. O CARP permite que vários hosts no mesmo segmento de rede compartilhem um endereço IP. Configure o CARP em ambos os nós do cluster de acordo com a documentação disponível em Seção 31.10, “Protocolo Comum de Redundância de Endereços (CARP)”. Neste exemplo, cada nó terá seu próprio endereço de gerenciamento IP e um endereço IP compartilhado de 172.16.0.254
. O nó principal HAST do cluster deve ser o nó mestre CARP.
O pool HAST criado na seção anterior está agora pronto para ser exportado para os outros hosts da rede. Isso pode ser feito exportando-o através do NFS ou Samba, usando o endereço IP 172.16.0.254
compartilhado. O único problema que permanece não resolvido é um failover automático caso o nó primário falhe.
Caso as interfaces do CARP subam ou desçam, o sistema operacional FreeBSD gera um evento devd(8), tornando possível observar mudanças de estado nas interfaces do CARP. Uma alteração de estado na interface CARP é uma indicação de que um dos nós falhou ou voltou a ficar online. Esses eventos de mudança de estado tornam possível executar um script que manipulará automaticamente o failover HAST.
Para capturar mudanças de estado nas interfaces do CARP, adicione esta configuração ao /etc/devd.conf
em cada nó:
notify 30 { match "system" "IFNET"; match "subsystem" "carp0"; match "type" "LINK_UP"; action "/usr/local/sbin/carp-hast-switch master"; }; notify 30 { match "system" "IFNET"; match "subsystem" "carp0"; match "type" "LINK_DOWN"; action "/usr/local/sbin/carp-hast-switch slave"; };
Se os sistemas estiverem executando o FreeBSD 10 ou superior, substitua carp0
pelo nome da interface configurada CARP.
Reinicie o devd(8) em ambos os nós para colocar a nova configuração em vigor:
#
service devd restart
Quando o estado da interface especificada é alterado subindo ou descendo, o sistema gera uma notificação, permitindo que o subsistema devd(8) execute o script de failover automático especificado, /usr/local/sbin/carp-hast-switch
. Para maiores esclarecimentos sobre esta configuração, consulte devd.conf(5).
Aqui está um exemplo de um script de failover automatizado:
#!/bin/sh
# Original script by Freddie Cash <fjwcash@gmail.com>
# Modified by Michael W. Lucas <mwlucas@BlackHelicopters.org>
# and Viktor Petersson <vpetersson@wireload.net>
# The names of the HAST resources, as listed in /etc/hast.conf
resources="test
"
# delay in mounting HAST resource after becoming master
# make your best guess
delay=3
# logging
log="local0.debug"
name="carp-hast"
# end of user configurable stuff
case "$1" in
master)
logger -p $log -t $name "Switching to primary provider for ${resources}."
sleep ${delay}
# Wait for any "hastd secondary" processes to stop
for disk in ${resources}; do
while $( pgrep -lf "hastd: ${disk} \(secondary\)" > /dev/null 2>&1 ); do
sleep 1
done
# Switch role for each disk
hastctl role primary ${disk}
if [ $? -ne 0 ]; then
logger -p $log -t $name "Unable to change role to primary for resource ${disk}."
exit 1
fi
done
# Wait for the /dev/hast/* devices to appear
for disk in ${resources}; do
for I in $( jot 60 ); do
[ -c "/dev/hast/${disk}" ] && break
sleep 0.5
done
if [ ! -c "/dev/hast/${disk}" ]; then
logger -p $log -t $name "GEOM provider /dev/hast/${disk} did not appear."
exit 1
fi
done
logger -p $log -t $name "Role for HAST resources ${resources} switched to primary."
logger -p $log -t $name "Mounting disks."
for disk in ${resources}; do
mkdir -p /hast/${disk}
fsck -p -y -t ufs /dev/hast/${disk}
mount /dev/hast/${disk} /hast/${disk}
done
;;
slave)
logger -p $log -t $name "Switching to secondary provider for ${resources}."
# Switch roles for the HAST resources
for disk in ${resources}; do
if ! mount | grep -q "^/dev/hast/${disk} on "
then
else
umount -f /hast/${disk}
fi
sleep $delay
hastctl role secondary ${disk} 2>&1
if [ $? -ne 0 ]; then
logger -p $log -t $name "Unable to switch role to secondary for resource ${disk}."
exit 1
fi
logger -p $log -t $name "Role switched to secondary for resource ${disk}."
done
;;
esac
Em poucas palavras, o script executa essas ações quando um nó se torna mestre:
Promove o pool de HAST para primário no outro nó.
Verifica o sistema de arquivos no pool HAST.
Monta o pool.
Quando um nó se torna secundário:
Desmonta o conjunto HAST.
Degrada o pool HAST para secundário.
Este é apenas um script de exemplo que serve como prova de conceito. Ele não manipula todos os cenários possíveis e pode ser estendido ou alterado de qualquer forma, por exemplo, para iniciar ou interromper os serviços necessários.
Para este exemplo, foi utilizado um sistema de arquivos padrão UFS. Para reduzir o tempo necessário para a recuperação, é possível usar um sistema de arquivos UFS ou ZFS com journal ativado.
Informações mais detalhadas com exemplos adicionais podem ser encontradas em http://wiki.FreeBSD.org/HAST.
O HAST geralmente deve funcionar sem problemas. No entanto, como acontece com qualquer outro produto de software, pode haver momentos em que ele não funciona como deveria. As origens dos problemas podem ser diferentes, mas a regra geral é garantir que o horário esteja sincronizado entre os nós do cluster.
Quando estiver fazendo troubleshooting no HAST, o nível de depuração de hastd(8) deve ser aumentado iniciando hastd
com -d
. Esse argumento pode ser especificado várias vezes para aumentar ainda mais o nível de depuração. Considere também usar -F
, que inicia o hastd
em primeiro plano.
Split-brain ocorre quando os nós do cluster não conseguem se comunicar entre si e ambos são configurados como primários. Esta é uma condição perigosa porque permite que ambos os nós façam alterações incompatíveis nos dados. Esse problema deve ser corrigido manualmente pelo administrador do sistema.
O administrador deve decidir qual nó tem alterações mais importantes ou executar a mesclagem manualmente. Então, deixe o HAST executar a sincronização completa do nó que possui os dados quebrados. Para fazer isso, emita esses comandos no nó que precisa ser ressincronizado:
#
hastctl role init
test
#
hastctl create
test
#
hastctl role secondary
test
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.