You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows PowerShell脚本远程Redis临时主从同步故障排查

Redis临时主从同步的PowerShell脚本问题

由于项目架构限制,两台远程Linux主机上的Redis均为主库,无法长期维持主从关系,需通过PowerShell脚本结合SSH会话,临时建立主从关系完成数据同步,预期流程为:

  • 与从库服务器建立SSH连接
  • 在从库执行SLAVEOF $masterServer $masterPort建立临时主从
  • 完成数据同步后执行SLAVEOF NO ONE解除主从

当前遇到两个问题:

  1. 手动执行SYNC命令时失败,报错:

    SYNC with master failed: -NOMASTERLINK Can't SYNC while not connected with my master
    但设置主从的命令已返回{OK},重复执行会提示{OK Already connected to specified master},说明主从关系已建立。

  2. 手动建立主从后执行SYNC命令,出现超时错误:

    ForEach-Object : Exception calling "EndExecute" with "1" argument(s): "Command 'echo SYNC | redis-cli' has timed out."
    推测SYNC执行后bash进入监听状态,需按Ctrl+C退出,但发送send -- \x03无效。

附原PowerShell脚本:

param(
    [Parameter(Mandatory=$true, Position=0)]
    [string] $MasterServer,

    [Parameter(Mandatory=$true, Position=1)]
    [string] $MasterPort,

    [Parameter(Mandatory=$true, Position=2)]
    [string] $ReplicaServer,

    [Parameter(Mandatory=$true, Position=3)]
    [string] $UserReplicaServer,

    [Parameter(Mandatory=$true, Position=4)]
    [string] $PwdReplicaServer
)

$SecurePasswd = ConvertTo-SecureString $PwdReplicaServer -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($UserReplicaServer, $SecurePasswd)

Write-Host "Connecting to Redis host over SSH..."
# Connect Over SSH and getting session id.
$SessionID = New-SSHSession -ComputerName $ReplicaServer -Credential $Credentials -Force

if($SessionID -eq $null){
    Write-Host "Error: An error occurred trying to setup the SSH session. Please check the connection string/credentials for the SSH session."
    exit 1
} else {
    Write-Host "SSH session created successfully. Running Redis SYNC."
}

# Commands.
$commands = @(
    @{
        Command = "echo SLAVEOF $MasterServer $MasterPort | redis-cli"
        Description = "Configure replication"
    },
    @{
        Command = "echo SYNC | redis-cli"
        Description = "Sync replication"
    },
    @{
        Command = "echo SLAVEOF NO ONE | redis-cli"
        Description = "Undo replication"
    }
)

# Execute commands on Redis Host
foreach ($command in $commands) {
    $result = Invoke-SSHCommand -Index $SessionID.sessionid -Command $command.Command
    if ($result.ExitStatus -ne 0) {
        Write-Host "Error: Failed to execute command '$($command.Command)'. Description: $($command.Description) Error message: $($result.StandardError)"
        exit 1
    }
    Write-Host "Success: Command '$($command.Command)' executed successfully. Description: $($command.Description)"
}

Write-Host "Script Worked and Finished!"

问题原因及解决方案

核心问题原因

Redis从库在执行SLAVEOF命令后,会自动发起SYNC全量同步,无需手动执行SYNC命令:

  • 手动执行SYNC时,从库已处于主从同步状态,Redis不允许手动触发SYNC,因此报错NOMASTERLINK;
  • 手动执行SYNC会导致redis-cli持续监听主库的数据流,不会自动退出,进而引发SSH命令超时。

修改后的脚本逻辑

  1. 移除手动执行SYNC的步骤;
  2. 增加等待逻辑,确保从库完成全量同步后再解除主从关系。

修改后的PowerShell脚本

param(
    [Parameter(Mandatory=$true, Position=0)]
    [string] $MasterServer,

    [Parameter(Mandatory=$true, Position=1)]
    [string] $MasterPort,

    [Parameter(Mandatory=$true, Position=2)]
    [string] $ReplicaServer,

    [Parameter(Mandatory=$true, Position=3)]
    [string] $UserReplicaServer,

    [Parameter(Mandatory=$true, Position=4)]
    [string] $PwdReplicaServer,

    [Parameter(Mandatory=$false, Position=5)]
    [int] $SyncTimeoutSeconds = 300
)

$SecurePasswd = ConvertTo-SecureString $PwdReplicaServer -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($UserReplicaServer, $SecurePasswd)

Write-Host "Connecting to Redis host over SSH..."
$SessionID = New-SSHSession -ComputerName $ReplicaServer -Credential $Credentials -Force

if($SessionID -eq $null){
    Write-Host "Error: Failed to setup SSH session. Check connection/credentials."
    exit 1
} 
Write-Host "SSH session created successfully."

# 1. 设置临时主从关系
$setupCommand = "echo SLAVEOF $MasterServer $MasterPort | redis-cli"
$result = Invoke-SSHCommand -Index $SessionID.sessionid -Command $setupCommand
if ($result.ExitStatus -ne 0) {
    Write-Host "Error: Failed to setup replication. Error: $($result.StandardError)"
    exit 1
}
Write-Host "Success: Replication setup initiated."

# 2. 等待同步完成
Write-Host "Waiting for full sync to complete..."
$startTime = Get-Date
$syncCompleted = $false
while (-not $syncCompleted) {
    # 检查主从连接状态和同步进度
    $infoCmd = "redis-cli info replication | grep -E 'master_link_status|sync_full'"
    $infoResult = Invoke-SSHCommand -Index $SessionID.sessionid -Command $infoCmd
    
    if ($infoResult.ExitStatus -ne 0) {
        Write-Host "Error: Failed to check replication status. Error: $($infoResult.StandardError)"
        exit 1
    }

    $statusOutput = $infoResult.Output
    $masterConnected = $statusOutput -match 'master_link_status:up'
    $fullSyncDone = $statusOutput -match 'sync_full:1'

    if ($masterConnected -and $fullSyncDone) {
        $syncCompleted = $true
        Write-Host "Success: Full sync completed."
    } else {
        $elapsed = (Get-Date) - $startTime
        if ($elapsed.TotalSeconds -ge $SyncTimeoutSeconds) {
            Write-Host "Error: Sync timed out after $SyncTimeoutSeconds seconds."
            # 尝试解除主从关系后退出
            Invoke-SSHCommand -Index $SessionID.sessionid -Command "echo SLAVEOF NO ONE | redis-cli"
            exit 1
        }
        Write-Host "Sync in progress... Elapsed: $($elapsed.Seconds)s"
        Start-Sleep -Seconds 5
    }
}

# 3. 解除主从关系
$undoCommand = "echo SLAVEOF NO ONE | redis-cli"
$result = Invoke-SSHCommand -Index $SessionID.sessionid -Command $undoCommand
if ($result.ExitStatus -ne 0) {
    Write-Host "Error: Failed to undo replication. Error: $($result.StandardError)"
    exit 1
}
Write-Host "Success: Replication undone. Redis is now master again."

Write-Host "Script completed successfully!"

额外说明

  • 脚本增加了同步超时参数$SyncTimeoutSeconds,默认5分钟,可根据数据量调整;
  • 通过redis-cli info replication检查master_link_status:up确认主从连接正常,sync_full:1确认全量同步完成;
  • 若同步超时,脚本会尝试解除主从关系后退出,避免从库长期处于从节点状态。

内容的提问来源于stack exchange,提问作者Retrosec6

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:20:38