AWS EC2 Primary与Secondary实例间实时复制文件服务方案咨询
Great question! Let’s break this down into two parts: AWS native solutions (the easiest, most reliable route) and self-developed scripts/tools if you need full control.
If you want to avoid building and maintaining custom code, AWS has a purpose-built service that fits your exact needs:
AWS Elastic Disaster Recovery (DRS)
This is the go-to native service for real-time replication of EC2 instances (including all files, OS configurations, services, and daemon states) with near-zero Recovery Point Objective (RPO) and low Recovery Time Objective (RTO). Here’s how it works:
- Continuous block-level replication: It replicates every change on your primary EC2’s EBS volumes to a staging area in your secondary region/AZ, so data is always up-to-date.
- Instant failover: You can launch your secondary instance with a single click (or via API/CLI) and it will boot into an exact copy of your primary instance—all services, daemons, and configurations will be ready to run immediately.
- Auto-syncs configurations: It automatically replicates EC2 settings like security groups, IAM roles, network interfaces, and even OS-level configurations.
- Low overhead: The replication agent is lightweight and doesn’t impact your primary instance’s performance.
Other native options (less ideal for real-time needs):
- EBS Snapshots: Only do periodic (not real-time) replication, so you’ll lose data between snapshots.
- EBS Multi-Attach: Lets multiple EC2 instances share a single EBS volume, but it’s limited to the same Availability Zone and isn’t true replication (more for clustered workloads).
If you prefer to build a custom solution, here are the most practical approaches for Linux-based EC2 instances:
1. Rsync + Inotifywait (Real-Time File Sync)
This classic combo monitors file system changes on your primary instance and triggers immediate syncs to the secondary.
Step 1: Set Up SSH Key Authentication
First, enable passwordless SSH from primary to secondary to avoid manual input in scripts:
# On primary instance ssh-keygen -t rsa -N "" -f ~/.ssh/replication_key ssh-copy-id -i ~/.ssh/replication_key.pub ec2-user@<secondary-ip-or-hostname>
Step 2: Create the Replication Script
Save this as /usr/local/bin/replicate_to_secondary.sh and make it executable:
#!/bin/bash set -e # Define directories to monitor (add/remove as needed) MONITOR_DIRS="/var/www /etc /usr/local/bin /opt/my-app" SECONDARY_SSH="ec2-user@<secondary-ip-or-hostname>" SSH_KEY="/home/ec2-user/.ssh/replication_key" LOG_FILE="/var/log/replication.log" # Install dependencies if missing if ! command -v inotifywait &> /dev/null; then # For Amazon Linux/RHEL sudo yum install -y inotify-tools # For Ubuntu/Debian: sudo apt-get install -y inotify-tools fi # Create log directory if needed mkdir -p $(dirname $LOG_FILE) # Monitor each directory for changes for DIR in $MONITOR_DIRS; do echo "Starting monitor for $DIR at $(date)" >> $LOG_FILE inotifywait -m -r -e modify,create,delete,move "$DIR" | while read -r _ _ _; do # Sync directory to secondary (--delete ensures secondary matches primary exactly) rsync -avz --delete -e "ssh -i $SSH_KEY" "$DIR" "$SECONDARY_SSH:$DIR" echo "Synced $DIR to secondary at $(date)" >> $LOG_FILE done & done # Keep script running wait
Step 3: Run as a Systemd Service
To ensure the script runs continuously on boot, create a systemd service file /etc/systemd/system/replication.service:
[Unit] Description=Real-Time Replication to Secondary EC2 After=network.target [Service] User=root ExecStart=/usr/local/bin/replicate_to_secondary.sh Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Then enable and start the service:
sudo systemctl daemon-reload sudo systemctl enable --now replication.service
2. Lsyncd (Simplified Daemon for Sync)
Lsyncd is a lightweight daemon built on rsync and inotify that simplifies real-time sync configuration. It’s easier to maintain than a custom bash script.
Install & Configure Lsyncd
# Amazon Linux/RHEL sudo yum install -y lsyncd # Ubuntu/Debian: sudo apt-get install -y lsyncd
Create /etc/lsyncd.conf with your sync rules:
settings { logfile = "/var/log/lsyncd/lsyncd.log", statusFile = "/var/log/lsyncd/lsyncd.status", inotifyMode = "CloseWrite", maxProcesses = 4, } # Sync web app files sync { default.rsync, source = "/var/www", target = "ec2-user@<secondary-ip-or-hostname>:/var/www", rsync = { archive = true, compress = true, delete = true, rsh = "/usr/bin/ssh -i /home/ec2-user/.ssh/replication_key" } } # Sync system configurations sync { default.rsync, source = "/etc", target = "ec2-user@<secondary-ip-or-hostname>:/etc", rsync = { archive = true, compress = true, delete = true, rsh = "/usr/bin/ssh -i /home/ec2-user/.ssh/replication_key" } }
Start and enable the service:
sudo systemctl enable --now lsyncd.service
Critical Notes for Custom Solutions
- Service/Daemon Sync: File sync only copies configs and binaries—you’ll need additional steps to ensure secondary services match primary state. For example, sync enabled services with:
# On primary systemctl list-unit-files --type=service --state=enabled | grep -v "^#" > /tmp/enabled_services.txt rsync -avz -e "ssh -i $SSH_KEY" /tmp/enabled_services.txt "$SECONDARY_SSH:/tmp/" # On secondary (can add this to your sync script) ssh -i $SSH_KEY "$SECONDARY_SSH" "while read line; do SERVICE=\$(echo \$line | awk '{print \$1}'); systemctl enable --now \$SERVICE; done < /tmp/enabled_services.txt" - Database Sync: Never sync database files directly (they’re locked during runtime). Use database-native replication:
- MySQL/MariaDB: Binlog-based master-slave replication
- PostgreSQL: Streaming replication
- Monitoring: Add alerts for sync failures (e.g., use CloudWatch Alarms on your log file, or a tool like
monitto restart the sync service if it crashes).
内容的提问来源于stack exchange,提问作者zookastos

