第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-id

2.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.sh

3. 迁移策略

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-12345678

3.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 v1

3.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 prod

4. 应用迁移

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_ID

4.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-replication

5. 数据迁移

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_ARN

5.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/snowball

6. 迁移验证

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.sh

6.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云平台。

实施步骤

  1. 迁移准备
# 创建迁移计划
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)
  1. 数据迁移
# 使用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
  1. 应用迁移
# 创建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。

实施步骤

  1. 迁移准备
# 评估数据库大小
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)
  1. 数据迁移
# 使用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
  1. 验证和切换
# 验证数据完整性
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

课后练习

  1. 基础练习

    • 评估应用迁移需求
    • 创建迁移计划
    • 执行简单的应用迁移
  2. 进阶练习

    • 迁移数据库到云
    • 配置数据同步
    • 验证迁移结果
  3. 挑战练习

    • 实施零停机迁移
    • 迁移大数据集
    • 优化迁移性能
  4. 思考问题

    • 如何选择合适的迁移策略?
    • 如何确保迁移过程中的数据安全?
    • 如何处理迁移失败的情况?

总结

本集详细介绍了Linux系统中云迁移的策略和方法,包括迁移评估、迁移策略、应用迁移、数据迁移、迁移验证以及迁移优化等内容。通过本集的学习,您应该能够:

  • 理解云迁移的概念和重要性
  • 掌握迁移评估和策略制定
  • 熟悉应用迁移的方法和工具
  • 学习数据迁移的最佳实践
  • 能够实施完整的云迁移项目

云迁移是企业数字化转型的重要步骤,它能够帮助企业提高灵活性、降低成本、加速创新。在实际项目中,应根据应用特点和业务需求制定详细的迁移计划,选择合适的迁移策略,并建立完善的验证和回滚机制,以确保迁移的成功和业务的连续性。

« 上一篇 混合云配置 下一篇 » Linux文档系统