如何将文件从本地数据中心复制到本地数据中心并进行一些故障转移?

如何将文件从本地数据中心复制到本地数据中心并进行一些故障转移?

我有一个脚本,它知道HOSTNAME它将在哪个脚本上运行,因为它有一个HOSTNAME变量来说明这一点,并且它是从外部传递的。我想检查HOSTNAME位于哪个数据中心,并在此基础上,我将从特定计算机复制文件。

  • 如果应用程序服务器HOSTNAME位于 PHX,那么它应该从holdermachine.phx.host.com.
  • 如果应用程序服务器HOSTNAME位于 SLC 中,那么它应该从holdermachine.slc.host.com.
  • 如果应用程序服务器HOSTNAME位于 LVS 中,那么它应该从holdermachine.lvs.host.com.

现在,对于故障转移情况,如果任何一个holdermachine发生故障,那么脚本应该从其他数据中心复制holdermachine(可以随机选择),但是一旦本地数据中心holdermachine备份,它应该开始从本地数据中心而不是远程数据中心复制holdermachine。另外,如果可能的话,请发送一封电子邮件,告知此问题holdermachine已关闭且没有响应,因此开始从远程复制holdermachine

截至目前,下面的脚本只会复制文件HOLDER_LOCATION_phx,我很困惑如何使上述逻辑工作。

#!/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."

现在我需要做的是——

  • 检查是否HOSTNAME为PHX、SLC、LVS。然后在此基础上开始从本地数据中心复制
  • 但是,如果本地数据中心持有者机器出现故障,则从远程数据中心持有者机器复制并发送有关此问题的电子邮件。此外,如果本地数据中心计算机是备份,则开始从本地数据中心计算机而不是远程数据中心计算机进行复制。

我们的应用程序服务器机器名称将是这样的。我们唯一需要检查的是.phx.or .slc.or.lvs.部分。而且phx,slc也没有必要lvs总是在同一位置,因为有时机器名称有一些额外的内容,然后后面跟着.phx.or.slc..lvs.,所以我们需要正确检查它。

appservermachineA.phx.host.com
appservermachineB.slc.host.com
appservermachineC.lvs.host.com

答案1

有几种方法可以相当轻松地拉出零件。例如:foo.bar.baz.code.provider.com

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

如果您的数据中心名称与这样的简单模式不匹配,您可以使用语句case,并基于完整 shell 模式进行匹配:

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

对于您的故障转移案例,您需要决定如何确定计算机已关闭。如果scp返回非零退出状态,最简单的方法是尝试不同的机器。这就是你正在做的事情||

(那里还有其他一些东西 - 例如,我很确定parallelcall 不起作用,因为它适用于命令,而不是 shell 函数)

答案2

根据 @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."

请注意,我完全不确定您的parallel电话是否有效。我还修复了您的脚本中的一些其他问题并对其进行了一些简化。自从您提到您稍后可能希望将其扩展到更多服务器以来,我保留了数组结构。请注意,如果这样做,您将需要循环访问数组中存储的服务器名称。目前,我只是使用每个元素中的第一个元素(例如${datacenter[0]})。

相关内容