Como copiar arquivos do datacenter local para o datacenter local e ter alguns casos de failover?

4

Eu tenho um script que sabe em qual HOSTNAME ele estará rodando, pois ele tem a variável HOSTNAME que informa sobre isso e está sendo passada de fora. Eu quero verificar qual datacenter que HOSTNAME é e com base nisso, vou copiar os arquivos da máquina particular.

  • Se o servidor de aplicativos HOSTNAME estiver em PHX, copie os arquivos de holdermachine.phx.host.com .
  • Se o servidor de aplicativos HOSTNAME estiver no SLC, copie os arquivos de holdermachine.slc.host.com .
  • Se o servidor de aplicativos HOSTNAME estiver em LVS, copie os arquivos de holdermachine.lvs.host.com .

Agora, para o caso de failover, se qualquer um dos holdermachine cair, o script deverá ser copiado de outro datacenter holdermachine (pode ser escolhido aleatoriamente), mas assim que o datacenter local holdermachine for salvo, ele deverá começar a copiar de seu local em vez de datacenter remoto holdermachine . Além disso, se possível, envie um e-mail informando que esse holdermachine está inativo e não está respondendo, portanto, começar a copiar do holdermachine remoto.

A partir de agora, o script abaixo só copiará arquivos de HOLDER_LOCATION_phx e confundirei como fazer a lógica acima funcionar.

#!/bin/bash

export PRIMARY=/test01/primary # copy PRIMARY_PARTITION into this folder
export SECONDARY=/test02/secondary # copy SECONDARY_PARTITION into this folder

readonly HOLDER_LOCATION_phx=(holdermachine.phx.host.com) # we might have more machines in future
readonly HOLDER_LOCATION_slc=(holdermachine.slc.host.com) # we might have more machines in future
readonly HOLDER_LOCATION_lvs=(holdermachine.lvs.host.com) # we might have more machines in future

export HOLDER_LOCATION_1=${HOLDER_LOCATION_phx[0]}
export HOLDER_LOCATION_2=${HOLDER_LOCATION_slc[0]}
export HOLDER_LOCATION_3=${HOLDER_LOCATION_lvs[0]}

PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers and it is being passed from outisde
SECONDARY_PARTITION=(1643 1103 1372 1096 1369 1568) # this will have more file numbers and it is being passed from outisde

export FILE_LOCATION=/batch/data/pk_snapshot
readonly HOSTNAME=$hostname # this is the hostname on which this script will be running where we are copying the files.
readonly FILE_TIMESTAMP=$file_timestamp

export dir3=$FILE_LOCATION/$FILE_TIMESTAMP

# I need to delete before copying the files.
find "$PRIMARY" -mindepth 1 -delete
find "$SECONDARY" -mindepth 1 -delete

do_Copy() {
  el=$1
  PRIMSEC=$2
  scp david@$HOLDER_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMSEC/. || scp david@$HOLDER_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMSEC/. || scp david@$HOLDER_LOCATION_3:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMSEC/.
}
export -f do_Copy

# copying 10 files in parallel simultaneously in primary and secondary folder
parallel --retries 10 -j 10 do_Copy {} $PRIMARY ::: "${PRIMARY_PARTITION[@]}" &
parallel --retries 10 -j 10 do_Copy {} $SECONDARY ::: "${SECONDARY_PARTITION[@]}" &
wait    

echo "All files copied."

Agora, o que preciso fazer é -

  • Verifique se o HOSTNAME está em PHX, SLC ou LVS. E, em seguida, com base nessa cópia inicial do datacenter local
  • Mas se a máquina do suporte do datacenter local estiver inoperante, copie da máquina do suporte do datacenter remoto e envie um e-mail sobre isso. Além disso, se a máquina do datacenter local for backup, inicie a cópia a partir do local, em vez do datacenter remoto.

Nosso nome da máquina do servidor de aplicativos será assim. A única coisa que precisamos verificar é .phx. ou .slc. ou .lvs. porção. Também não é necessário que phx , slc e lvs estejam sempre no mesmo local bcoz. Às vezes, o nome da máquina tem algum material extra e seguido por .phx. ou .slc. ou .lvs. , então precisamos para verificar corretamente.

appservermachineA.phx.host.com
appservermachineB.slc.host.com
appservermachineC.lvs.host.com
    
por arsenal 01.04.2015 / 23:31

2 respostas

3

Puxar a parte foo.bar.baz.code.provider.com pode ser feito com bastante facilidade de duas maneiras. Por exemplo:

datacenter="$(echo "$HOSTNAME" | rev | cut -d. -f3 | rev)"

Se os nomes do data center não corresponderem a um padrão simples como esse, você poderá usar uma instrução case e corresponder com base em padrões completos de shell:

case "$HOSTNAME" in
    *phx.provider.com)       DATACENTER="dc1" ;;
    *lax.otherprovider.com)  DATACETNER="dc2" ;;
    *.weirdness.*)           DATACENTER="dc3" ;;
    # ⋮
esac

Para o seu caso de failover, você precisa decidir como vai determinar que uma máquina está inativa. O mais simples seria tentar uma máquina diferente se scp retornasse um status de saída diferente de zero. Isso é o que você está fazendo com || .

(Você tem algumas outras coisas lá também - por exemplo, tenho certeza de que parallel call não funcionará, porque funciona em comandos, não em funções de shell)

    
por 01.04.2015 / 23:46
3

Você poderia fazer algo assim, com base na resposta do @ derobert:

#!/usr/bin/env bash

primary="/test01/primary" # copy primary_partition into this folder
secondary="/test02/secondary" # copy secondary_partition into this folder

holder_location_phx=("holdermachine.phx.host.com") # we might have more machines in future
holder_location_slc=("holdermachine.slc.host.com") # we might have more machines in future
holder_location_lvs=("holdermachine.lvs.host.com") # we might have more machines in future

primary_partition=(550 274 2 546 278) # this will have more file numbers and it is being passed from outisde
secondary_partition=(1643 1103 1372 1096 1369 1568) # this will have more file numbers and it is being passed from outisde

file_location="/batch/data/pk_snapshot"
file_timestamp="$file_timestamp"

dir3="$file_location"/"$file_timestamp"

# I need to delete before copying the files.
find "$primary" -mindepth 1 -delete
find "$secondary" -mindepth 1 -delete

## Find where we are and choose the primary and alternative
## targets accordingly.
case "$HOSTNAME" in
    *phx.host.com) 
        datacenter=("${holder_location_phx[@]}")
        alternative1=("${holder_location_slc[@]}")
        alternative2=("${holder_location_lvs[@]}")
        ;;
    *lax.host.com) 
        datacenter=("${holder_location_lax[@]}")
        alternative1=("${holder_location_phx[@]}")
        alternative2=("${holder_location_lvs[@]}")
        ;;

    *lvs.host.com) 
        datacenter=("${holder_location_lvs[@]}")
        alternative1=("${holder_location_slc[@]}")
        alternative2=("${holder_location_phx[@]}")
        ;;

    *) echo "uknown host, exiting." && exit 1 ;;
    # ⋮
esac

do_copy() {
  el=$1
  primsec=$2
  scp david@"${datacenter[0]}":"$dir3"/new_weekly_2014_"$el"_200003_5.data "$primsec"/ || scp david@"${alternative1[0]}":"$dir3"/new_weekly_2014_"$el"_200003_5.data "$primsec"/ || scp david@"${alternative2[0]}":"$dir3"/new_weekly_2014_"$el"_200003_5.data "$primsec"/
}

export -f do_copy

# copying 10 files in parallel simultaneously in primary and secondary folder
parallel --retries 10 -j 10 do_copy {} "$primary" ::: "${primary_partition[@]}" &
parallel --retries 10 -j 10 do_copy {} "$secondary" ::: "${secondary_partition[@]}" &
wait    

echo "all files copied."

Observe que não tenho certeza de que sua chamada parallel funcionará. Eu também consertei alguns outros problemas no seu script e simplifiquei um pouco. Eu mantive a estrutura da matriz desde que você mencionou que você pode querer expandir isso para mais servidores mais tarde. Observe que, se você fizer isso, será necessário fazer um loop nos nomes de servidores armazenados nas matrizes. No momento, estou simplesmente usando o primeiro elemento em cada um deles (por exemplo, ${datacenter[0]} ).

    
por 02.04.2015 / 00:42