第270集:云迁移策略
教学目标
- 理解云迁移的概念和重要性
- 掌握迁移评估和策略制定
- 熟悉应用迁移的方法和工具
- 学习数据迁移的最佳实践
- 能够实施完整的云迁移项目
核心知识点
1. 云迁移概述
1.1 迁移动机
| 迁移动机 | 描述 | 收益 |
|---|---|---|
| 成本优化 | 降低IT基础设施成本 | 减少资本支出、按需付费 |
| 弹性扩展 | 根据需求动态扩展资源 | 提高资源利用率、应对峰值 |
| 创新加速 | 利用云服务快速创新 | 缩短产品上市时间 |
| 全球部署 | 在全球范围部署应用 | 提高用户体验、降低延迟 |
| 灾难恢复 | 建立高可用架构 | 提高业务连续性 |
1.2 迁移策略
+---------------------------------------------------+
| 迁移策略矩阵 |
+---------------------------------------------------+
| 重新构建 | 平台迁移 | 重新托管 |
| (Rebuild) | (Replatform) | (Rehost) |
| 高投入 | 中等投入 | 低投入 |
| 高收益 | 中等收益 | 低收益 |
+---------------------------------------------------+
| 重新架构 | 保留 | 退役 |
| (Refactor) | (Retain) | (Retire) |
| 最高投入 | 无投入 | 无投入 |
| 最高收益 | 无收益 | 节省成本 |
+---------------------------------------------------+2. 迁移评估
2.1 应用评估
# 使用AWS Migration Hub评估应用
# 安装Application Discovery Agent
wget https://aws-application-discovery-agent-us-east-1.s3.amazonaws.com/linux/latest/aws-discovery-agent.tar.gz
tar -xzf aws-discovery-agent.tar.gz
sudo bash install
# 配置Agent
sudo /opt/aws/aws-discovery-agent/bin/aws-discovery-agentctl register \
--collector-id my-collector-id \
--aws-access-key-id AKIAIOSFODNN7EXAMPLE \
--aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# 启动Agent
sudo /opt/aws/aws-discovery-agent/bin/aws-discovery-agentctl start
# 查看发现的应用
aws migrationhub list-discovered-resources \
--max-results 100
# 导出评估报告
aws migrationhub get-application-state \
--application-id my-application-id2.2 成本评估
# 使用AWS TCO Calculator评估成本
# 创建成本估算
aws ce get-cost-and-usage \
--time-period Start=2024-01-01,End=2024-01-31 \
--granularity MONTHLY \
--metrics BlendedCost \
--group-by SERVICE
# 使用AWS Pricing Calculator
# 访问 https://calculator.aws/
# 创建成本对比脚本
cat > cost-comparison.sh << 'EOF'
#!/bin/bash
# 本地成本
LOCAL_SERVER_COST=1000
LOCAL_STORAGE_COST=500
LOCAL_NETWORK_COST=200
LOCAL_TOTAL=$((LOCAL_SERVER_COST + LOCAL_STORAGE_COST + LOCAL_NETWORK_COST))
# 云成本
CLOUD_COMPUTE_COST=800
CLOUD_STORAGE_COST=300
CLOUD_NETWORK_COST=100
CLOUD_TOTAL=$((CLOUD_COMPUTE_COST + CLOUD_STORAGE_COST + CLOUD_NETWORK_COST))
# 计算节省
SAVINGS=$((LOCAL_TOTAL - CLOUD_TOTAL))
SAVINGS_PERCENTAGE=$(echo "scale=2; $SAVINGS / $LOCAL_TOTAL * 100" | bc)
echo "本地成本: $LOCAL_TOTAL"
echo "云成本: $CLOUD_TOTAL"
echo "节省: $SAVINGS ($SAVINGS_PERCENTAGE%)"
EOF
chmod +x cost-comparison.sh
./cost-comparison.sh3. 迁移策略
3.1 Rehosting(重新托管)
# 使用AWS Server Migration Service (SMS)
# 安装SMS Connector
wget https://aws-server-migration-service-us-east-1.s3.amazonaws.com/latest/aws-sms-connector.tar.gz
tar -xzf aws-sms-connector.tar.gz
sudo bash install
# 配置Connector
sudo /opt/aws/sms/bin/aws-sms-connector configure \
--collector-id my-collector-id \
--aws-access-key-id AKIAIOSFODNN7EXAMPLE \
--aws-secret-access-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# 创建复制任务
aws sms create-replication-job \
--server-id server-12345678 \
--frequency 12 \
--run-once \
--description "Migrate web server to AWS"
# 查看任务状态
aws sms describe-replication-jobs \
--replication-job-ids job-12345678
# 启动迁移
aws sms start-on-demand-replication-run \
--replication-job-id job-123456783.2 Replatforming(平台迁移)
# 使用AWS Elastic Beanstalk
# 创建应用程序
aws elasticbeanstalk create-application \
--application-name my-app
# 创建环境
aws elasticbeanstalk create-environment \
--application-name my-app \
--environment-name my-env \
--solution-stack-name "64bit Amazon Linux 2 v5.8.0 running Python 3.8" \
--option-settings file://options.json
# options.json
cat > options.json << 'EOF'
[
{
"Namespace": "aws:autoscaling:launchconfiguration",
"OptionName": "InstanceType",
"Value": "t3.micro"
},
{
"Namespace": "aws:autoscaling:asg",
"OptionName": "MinSize",
"Value": "2"
},
{
"Namespace": "aws:autoscaling:asg",
"OptionName": "MaxSize",
"Value": "4"
}
]
EOF
# 部署应用
aws elasticbeanstalk create-application-version \
--application-name my-app \
--version-label v1 \
--source-bundle S3Bucket=my-bucket,S3Key=app.zip
aws elasticbeanstalk update-environment \
--environment-name my-env \
--version-label v13.3 Refactoring(重新架构)
# 使用AWS Lambda重构应用
# 创建Lambda函数
aws lambda create-function \
--function-name my-function \
--runtime python3.9 \
--role arn:aws:iam::123456789012:role/lambda-role \
--handler index.handler \
--code S3Bucket=my-bucket,S3Key=function.zip \
--memory-size 128 \
--timeout 30
# 创建API Gateway
API_ID=$(aws apigateway create-rest-api \
--name my-api \
--query 'id' \
--output text)
# 创建资源
RESOURCE_ID=$(aws apigateway create-resource \
--rest-api-id $API_ID \
--parent-id $ROOT_ID \
--path-part api \
--query 'id' \
--output text)
# 创建方法
aws apigateway put-method \
--rest-api-id $API_ID \
--resource-id $RESOURCE_ID \
--http-method POST \
--authorization-type NONE
# 集成Lambda
aws apigateway put-integration \
--rest-api-id $API_ID \
--resource-id $RESOURCE_ID \
--http-method POST \
--type AWS_PROXY \
--integration-http-method POST \
--integration-uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:my-function/invocations
# 部署API
aws apigateway create-deployment \
--rest-api-id $API_ID \
--stage-name prod4. 应用迁移
4.1 Web应用迁移
# 迁移Nginx应用
# 创建AMI
INSTANCE_ID="i-1234567890abcdef0"
# 创建AMI
AMI_ID=$(aws ec2 create-image \
--instance-id $INSTANCE_ID \
--name "web-server-ami" \
--description "Web server AMI" \
--query 'ImageId' \
--output text)
echo "AMI ID: $AMI_ID"
# 等待AMI可用
aws ec2 wait image-available --image-ids $AMI_ID
# 在新区域复制AMI
NEW_AMI_ID=$(aws ec2 copy-image \
--source-region us-east-1 \
--source-image-id $AMI_ID \
--name "web-server-ami-west" \
--region us-west-2 \
--query 'ImageId' \
--output text)
echo "New AMI ID: $NEW_AMI_ID"
# 在新区域启动实例
NEW_INSTANCE_ID=$(aws ec2 run-instances \
--image-id $NEW_AMI_ID \
--instance-type t3.micro \
--key-name my-key-pair \
--security-group-ids sg-12345678 \
--subnet-id subnet-12345678 \
--region us-west-2 \
--query 'Instances[0].InstanceId' \
--output text)
echo "New Instance ID: $NEW_INSTANCE_ID"
# 配置负载均衡
aws elbv2 create-load-balancer \
--name my-load-balancer \
--subnets subnet-12345678 subnet-87654321 \
--security-groups sg-12345678
# 创建目标组
TARGET_GROUP_ARN=$(aws elbv2 create-target-group \
--name my-targets \
--protocol HTTP \
--port 80 \
--vpc-id vpc-12345678 \
--query 'TargetGroups[0].TargetGroupArn' \
--output text)
# 注册目标
aws elbv2 register-targets \
--target-group-arn $TARGET_GROUP_ARN \
--targets Id=$NEW_INSTANCE_ID4.2 数据库迁移
# 使用AWS DMS迁移数据库
# 创建复制实例
REPLICATION_INSTANCE_ARN=$(aws dms create-replication-instance \
--replication-instance-identifier my-replication-instance \
--replication-instance-class dms.t3.medium \
--allocated-storage 50 \
--vpc-security-group-ids sg-12345678 \
--publicly-accessible \
--query 'ReplicationInstance.ReplicationInstanceArn' \
--output text)
echo "Replication Instance ARN: $REPLICATION_INSTANCE_ARN"
# 创建源端点
SOURCE_ENDPOINT_ARN=$(aws dms create-endpoint \
--endpoint-identifier source-endpoint \
--endpoint-type source \
--engine-name mysql \
--username admin \
--password password \
--server-name source-db.example.com \
--port 3306 \
--database-name mydatabase \
--query 'Endpoint.EndpointArn' \
--output text)
echo "Source Endpoint ARN: $SOURCE_ENDPOINT_ARN"
# 创建目标端点
TARGET_ENDPOINT_ARN=$(aws dms create-endpoint \
--endpoint-identifier target-endpoint \
--endpoint-type target \
--engine-name aurora \
--username admin \
--password password \
--server-name my-cluster.cluster-12345678.us-east-1.rds.amazonaws.com \
--port 3306 \
--database-name mydatabase \
--query 'Endpoint.EndpointArn' \
--output text)
echo "Target Endpoint ARN: $TARGET_ENDPOINT_ARN"
# 创建复制任务
TASK_ARN=$(aws dms create-replication-task \
--replication-task-identifier my-replication-task \
--source-endpoint-arn $SOURCE_ENDPOINT_ARN \
--target-endpoint-arn $TARGET_ENDPOINT_ARN \
--replication-instance-arn $REPLICATION_INSTANCE_ARN \
--migration-type full-load \
--table-mappings file://table-mappings.json \
--query 'ReplicationTask.ReplicationTaskArn' \
--output text)
echo "Task ARN: $TASK_ARN"
# table-mappings.json
cat > table-mappings.json << 'EOF'
{
"rules": [
{
"rule-type": "selection",
"rule-id": "1",
"object-locator": {
"schema-name": "mydatabase",
"table-name": "%"
},
"rule-action": "include"
}
]
}
EOF
# 启动任务
aws dms start-replication-task \
--replication-task-arn $TASK_ARN \
--start-replication-task-type start-replication5. 数据迁移
5.1 文件迁移
# 使用AWS DataSync迁移文件
# 创建源位置
SOURCE_LOCATION_ARN=$(aws datasync create-location-nfs \
--server-hostname 192.168.1.100 \
--subdirectory /data \
--mount-options file://mount-options.json \
--query 'LocationArn' \
--output text)
echo "Source Location ARN: $SOURCE_LOCATION_ARN"
# 创建目标位置
DESTINATION_LOCATION_ARN=$(aws datasync create-location-s3 \
--s3-bucket-arn arn:aws:s3:::my-bucket \
--s3-config BucketAccessRoleArn=arn:aws:iam::123456789012:role/DataSyncS3Role \
--query 'LocationArn' \
--output text)
echo "Destination Location ARN: $DESTINATION_LOCATION_ARN"
# 创建同步任务
TASK_ARN=$(aws datasync create-task \
--source-location-arn $SOURCE_LOCATION_ARN \
--destination-location-arn $DESTINATION_LOCATION_ARN \
--cloud-watch-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:/aws/datasync \
--name nfs-to-s3-sync \
--options file://task-options.json \
--query 'TaskArn' \
--output text)
echo "Task ARN: $TASK_ARN"
# 启动任务
EXECUTION_ARN=$(aws datasync start-task-execution \
--task-arn $TASK_ARN \
--query 'ExecutionArn' \
--output text)
echo "Execution ARN: $EXECUTION_ARN"
# 查看任务状态
aws datasync describe-task-execution \
--task-arn $TASK_ARN \
--execution-arn $EXECUTION_ARN5.2 大数据迁移
# 使用AWS Snowball迁移大数据
# 创建Snowball作业
JOB_ID=$(aws snowball create-job \
--job-type IMPORT \
--resources file://resources.json \
--description "Migrate big data to AWS" \
--address-id address-12345678 \
--shipping-option SECOND_DAY \
--snowball-capacity T100 \
--snowball-type EDGE \
--query 'JobId' \
--output text)
echo "Job ID: $JOB_ID"
# resources.json
cat > resources.json << 'EOF'
{
"S3Resources": [
{
"BucketArn": "arn:aws:s3:::my-bucket",
"KeyRange": {
"BeginMarker": "",
"EndMarker": ""
}
}
]
}
EOF
# 查看作业状态
aws snowball describe-job \
--job-id $JOB_ID
# 配置Snowball客户端
# 下载客户端
wget https://snowball-client.s3.amazonaws.com/latest/snowball-client-linux.bin
# 安装客户端
chmod +x snowball-client-linux.bin
sudo ./snowball-client-linux.bin
# 配置客户端
snowball client configure \
--endpoint https://snowball-device-ip \
--manifest file://manifest.bin \
--unlock-code unlock-code
# 启动传输
snowball cp -r /local/data /mnt/snowball6. 迁移验证
6.1 功能验证
# 创建验证脚本
cat > verify-migration.sh << 'EOF'
#!/bin/bash
# 验证Web服务
echo "Verifying web service..."
curl -f http://new-instance-ip/health || exit 1
# 验证数据库连接
echo "Verifying database connection..."
mysql -h new-db-endpoint -u admin -ppassword -e "SELECT 1" || exit 1
# 验证数据完整性
echo "Verifying data integrity..."
SOURCE_COUNT=$(mysql -h source-db -u admin -ppassword -e "SELECT COUNT(*) FROM mytable" -s)
TARGET_COUNT=$(mysql -h target-db -u admin -ppassword -e "SELECT COUNT(*) FROM mytable" -s)
if [ "$SOURCE_COUNT" -eq "$TARGET_COUNT" ]; then
echo "Data integrity verified"
else
echo "Data integrity check failed"
exit 1
fi
# 验证性能
echo "Verifying performance..."
RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}' http://new-instance-ip/api)
echo "Response time: $RESPONSE_TIME seconds"
if (( $(echo "$RESPONSE_TIME < 1.0" | bc -l) )); then
echo "Performance verified"
else
echo "Performance check failed"
exit 1
fi
echo "All verifications passed"
EOF
chmod +x verify-migration.sh
./verify-migration.sh6.2 性能验证
# 使用Apache Bench进行性能测试
# 安装Apache Bench
sudo apt-get install apache2-utils
# 测试本地应用
ab -n 1000 -c 10 http://local-app-ip/
# 测试云应用
ab -n 1000 -c 10 http://cloud-app-ip/
# 使用JMeter进行性能测试
# 安装JMeter
wget https://downloads.apache.org//jmeter/binaries/apache-jmeter-5.6.tgz
tar -xzf apache-jmeter-5.6.tgz
cd apache-jmeter-5.6
# 创建测试计划
cat > test-plan.jmx << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan">
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables"/>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group">
<intProp name="ThreadGroup.num_threads">100</intProp>
<intProp name="ThreadGroup.ramp_time">10</intProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request">
<stringProp name="HTTPSampler.domain">cloud-app-ip</stringProp>
<stringProp name="HTTPSampler.port">80</stringProp>
<stringProp name="HTTPSampler.path">/api</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
</HTTPSamplerProxy>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
EOF
# 运行测试
./bin/jmeter -n -t test-plan.jmx -l results.jtl实用案例分析
案例1:企业应用云迁移
场景描述
将企业级Web应用从本地数据中心迁移到AWS云平台。
实施步骤
- 迁移准备
# 创建迁移计划
cat > migration-plan.md << 'EOF'
# 迁移计划
## 迁移目标
- 将Web应用迁移到AWS
- 确保零停机时间
- 优化性能和成本
## 迁移范围
- Web服务器(3台)
- 应用服务器(5台)
- 数据库(MySQL主从)
- 文件存储(10TB)
## 迁移策略
- Web和应用服务器:Rehosting
- 数据库:Replatforming
- 文件存储:Refactoring
## 迁移时间表
- 第1周:评估和规划
- 第2周:基础设施准备
- 第3周:数据迁移
- 第4周:应用迁移
- 第5周:验证和优化
EOF
# 创建AWS基础设施
# 创建VPC
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--query 'Vpc.VpcId' \
--output text)
# 创建子网
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a \
--query 'Subnet.SubnetId' \
--output text)
PRIVATE_SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.2.0/24 \
--availability-zone us-east-1a \
--query 'Subnet.SubnetId' \
--output text)
# 创建安全组
WEB_SG_ID=$(aws ec2 create-security-group \
--group-name web-sg \
--description "Web server security group" \
--vpc-id $VPC_ID \
--query 'GroupId' \
--output text)
aws ec2 authorize-security-group-ingress \
--group-id $WEB_SG_ID \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
# 创建RDS数据库
DB_SUBNET_GROUP_NAME="my-db-subnet-group"
aws rds create-db-subnet-group \
--db-subnet-group-name $DB_SUBNET_GROUP_NAME \
--db-subnet-group-description "DB subnet group" \
--subnet-ids $PRIVATE_SUBNET_ID
DB_INSTANCE_ID=$(aws rds create-db-instance \
--db-instance-identifier my-db \
--db-instance-class db.t3.medium \
--engine mysql \
--master-username admin \
--master-user-password password \
--allocated-storage 100 \
--db-subnet-group-name $DB_SUBNET_GROUP_NAME \
--vpc-security-group-ids $WEB_SG_ID \
--query 'DBInstance.DBInstanceIdentifier' \
--output text)- 数据迁移
# 使用DMS迁移数据库
# 创建复制实例
REPLICATION_INSTANCE_ARN=$(aws dms create-replication-instance \
--replication-instance-identifier my-replication-instance \
--replication-instance-class dms.t3.medium \
--allocated-storage 50 \
--vpc-security-group-ids $WEB_SG_ID \
--publicly-accessible \
--query 'ReplicationInstance.ReplicationInstanceArn' \
--output text)
# 创建源端点
SOURCE_ENDPOINT_ARN=$(aws dms create-endpoint \
--endpoint-identifier source-endpoint \
--endpoint-type source \
--engine-name mysql \
--username admin \
--password password \
--server-name source-db.example.com \
--port 3306 \
--database-name mydatabase \
--query 'Endpoint.EndpointArn' \
--output text)
# 创建目标端点
TARGET_ENDPOINT_ARN=$(aws dms create-endpoint \
--endpoint-identifier target-endpoint \
--endpoint-type target \
--engine-name aurora \
--username admin \
--password password \
--server-name my-db.cluster-12345678.us-east-1.rds.amazonaws.com \
--port 3306 \
--database-name mydatabase \
--query 'Endpoint.EndpointArn' \
--output text)
# 创建复制任务
TASK_ARN=$(aws dms create-replication-task \
--replication-task-identifier my-replication-task \
--source-endpoint-arn $SOURCE_ENDPOINT_ARN \
--target-endpoint-arn $TARGET_ENDPOINT_ARN \
--replication-instance-arn $REPLICATION_INSTANCE_ARN \
--migration-type full-load-and-cdc \
--table-mappings file://table-mappings.json \
--query 'ReplicationTask.ReplicationTaskArn' \
--output text)
# 启动任务
aws dms start-replication-task \
--replication-task-arn $TASK_ARN \
--start-replication-task-type start-replication- 应用迁移
# 创建AMI
INSTANCE_ID="i-1234567890abcdef0"
AMI_ID=$(aws ec2 create-image \
--instance-id $INSTANCE_ID \
--name "web-server-ami" \
--description "Web server AMI" \
--query 'ImageId' \
--output text)
# 等待AMI可用
aws ec2 wait image-available --image-ids $AMI_ID
# 创建启动模板
LAUNCH_TEMPLATE_ID=$(aws ec2 create-launch-template \
--launch-template-name web-launch-template \
--launch-template-data file://launch-template-data.json \
--query 'LaunchTemplate.LaunchTemplateId' \
--output text)
# launch-template-data.json
cat > launch-template-data.json << 'EOF'
{
"ImageId": "'$AMI_ID'",
"InstanceType": "t3.micro",
"KeyName": "my-key-pair",
"SecurityGroupIds": ["'$WEB_SG_ID'"],
"SubnetId": "'$PUBLIC_SUBNET_ID'"
}
EOF
# 创建Auto Scaling组
ASG_NAME=$(aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name web-asg \
--launch-template LaunchTemplateId=$LAUNCH_TEMPLATE_ID \
--min-size 2 \
--max-size 5 \
--desired-capacity 3 \
--vpc-zone-identifier $PUBLIC_SUBNET_ID \
--query 'AutoScalingGroup.AutoScalingGroupName' \
--output text)
# 创建负载均衡
LB_ARN=$(aws elbv2 create-load-balancer \
--name my-load-balancer \
--subnets $PUBLIC_SUBNET_ID \
--security-groups $WEB_SG_ID \
--query 'LoadBalancers[0].LoadBalancerArn' \
--output text)
# 创建目标组
TARGET_GROUP_ARN=$(aws elbv2 create-target-group \
--name my-targets \
--protocol HTTP \
--port 80 \
--vpc-id $VPC_ID \
--query 'TargetGroups[0].TargetGroupArn' \
--output text)
# 配置Auto Scaling组
aws autoscaling attach-load-balancer-target-groups \
--auto-scaling-group-name $ASG_NAME \
--target-group-arns $TARGET_GROUP_ARN案例2:数据库云迁移
场景描述
将MySQL数据库从本地数据中心迁移到Amazon Aurora。
实施步骤
- 迁移准备
# 评估数据库大小
mysql -h source-db -u admin -ppassword -e "
SELECT
table_schema AS 'Database',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'
FROM information_schema.tables
GROUP BY table_schema;
"
# 创建Aurora集群
CLUSTER_ID=$(aws rds create-db-cluster \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-mysql \
--engine-version 5.7.mysql_aurora.2.11.2 \
--master-username admin \
--master-user-password password \
--vpc-security-group-ids $WEB_SG_ID \
--db-subnet-group-name $DB_SUBNET_GROUP_NAME \
--query 'DBCluster.DBClusterIdentifier' \
--output text)
# 创建实例
INSTANCE_ID=$(aws rds create-db-instance \
--db-instance-identifier my-aurora-instance \
--db-cluster-identifier $CLUSTER_ID \
--db-instance-class db.t3.medium \
--engine aurora-mysql \
--publicly-accessible \
--query 'DBInstance.DBInstanceIdentifier' \
--output text)- 数据迁移
# 使用mysqldump导出数据
mysqldump -h source-db -u admin -ppassword \
--single-transaction \
--routines \
--triggers \
--events \
--all-databases > dump.sql
# 上传到S3
aws s3 cp dump.sql s3://my-bucket/dump.sql
# 使用AWS DMS迁移
# 创建S3端点
S3_ENDPOINT_ARN=$(aws dms create-endpoint \
--endpoint-identifier s3-endpoint \
--endpoint-type source \
--engine-name s3 \
--s3-settings file://s3-settings.json \
--query 'Endpoint.EndpointArn' \
--output text)
# s3-settings.json
cat > s3-settings.json << 'EOF'
{
"BucketName": "my-bucket",
"BucketFolder": "dump",
"CompressionType": "GZIP"
}
EOF
# 创建复制任务
TASK_ARN=$(aws dms create-replication-task \
--replication-task-identifier s3-to-aurora-task \
--source-endpoint-arn $S3_ENDPOINT_ARN \
--target-endpoint-arn $TARGET_ENDPOINT_ARN \
--replication-instance-arn $REPLICATION_INSTANCE_ARN \
--migration-type full-load \
--table-mappings file://s3-table-mappings.json \
--query 'ReplicationTask.ReplicationTaskArn' \
--output text)
# 启动任务
aws dms start-replication-task \
--replication-task-arn $TASK_ARN \
--start-replication-task-type start-replication- 验证和切换
# 验证数据完整性
cat > verify-data.sh << 'EOF'
#!/bin/bash
# 比较源数据库和目标数据库的表数量
SOURCE_TABLES=$(mysql -h source-db -u admin -ppassword -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='mydatabase'" -s)
TARGET_TABLES=$(mysql -h target-db -u admin -ppassword -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='mydatabase'" -s)
echo "Source tables: $SOURCE_TABLES"
echo "Target tables: $TARGET_TABLES"
if [ "$SOURCE_TABLES" -eq "$TARGET_TABLES" ]; then
echo "Table count matches"
else
echo "Table count mismatch"
exit 1
fi
# 比较记录数
SOURCE_RECORDS=$(mysql -h source-db -u admin -ppassword -e "SELECT COUNT(*) FROM mydatabase.mytable" -s)
TARGET_RECORDS=$(mysql -h target-db -u admin -ppassword -e "SELECT COUNT(*) FROM mydatabase.mytable" -s)
echo "Source records: $SOURCE_RECORDS"
echo "Target records: $TARGET_RECORDS"
if [ "$SOURCE_RECORDS" -eq "$TARGET_RECORDS" ]; then
echo "Record count matches"
else
echo "Record count mismatch"
exit 1
fi
echo "Data verification passed"
EOF
chmod +x verify-data.sh
./verify-data.sh
# 切换DNS
# 更新Route53记录
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch file://dns-change.json
# dns-change.json
cat > dns-change.json << 'EOF'
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "myapp.example.com",
"Type": "CNAME",
"TTL": 300,
"ResourceRecords": [
{
"Value": "my-aurora-cluster.cluster-12345678.us-east-1.rds.amazonaws.com"
}
]
}
}
]
}
EOF课后练习
基础练习
- 评估应用迁移需求
- 创建迁移计划
- 执行简单的应用迁移
进阶练习
- 迁移数据库到云
- 配置数据同步
- 验证迁移结果
挑战练习
- 实施零停机迁移
- 迁移大数据集
- 优化迁移性能
思考问题
- 如何选择合适的迁移策略?
- 如何确保迁移过程中的数据安全?
- 如何处理迁移失败的情况?
总结
本集详细介绍了Linux系统中云迁移的策略和方法,包括迁移评估、迁移策略、应用迁移、数据迁移、迁移验证以及迁移优化等内容。通过本集的学习,您应该能够:
- 理解云迁移的概念和重要性
- 掌握迁移评估和策略制定
- 熟悉应用迁移的方法和工具
- 学习数据迁移的最佳实践
- 能够实施完整的云迁移项目
云迁移是企业数字化转型的重要步骤,它能够帮助企业提高灵活性、降低成本、加速创新。在实际项目中,应根据应用特点和业务需求制定详细的迁移计划,选择合适的迁移策略,并建立完善的验证和回滚机制,以确保迁移的成功和业务的连续性。