[Note]DataSync workshop – NFS to S3

https://catalog.us-east-1.prod.workshops.aws/datasync-migrate-millions-of-files/en-US

Deploy resources in the on-premises and in-cloud regions

Ở bài lab này, sẽ deploy on premises ở region Ohio (us-east-2) và Oregon (us-west-2)

CloudFormation template on premise:

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS DataSync Workshop - NFS Small Files Migration - On-Premises Region
Metadata:
  License:
    Description: |
      Copyright 2019-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.

      Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify,
      merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so.

      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Security
        Parameters:
          - kp
      - Label:
          default: AMI IDs (do not edit)
        Parameters:
          - linuxAmi
          - dsAmi
    ParameterLabels:
      kp:
        default: 'Access Key Pair:'
      linuxAmi:
        default: 'Linux'
      dsAmi:
        default: 'DataSync'

Parameters:
  kp:
    Description: '(NOTE: If you don''t see a key in the list you will need to create
      one from the EC2 console in this region)'
    Type: AWS::EC2::KeyPair::KeyName
  linuxAmi:
    Type : 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
  dsAmi:
    Type : 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/datasync/ami'

Resources:

  # Create a dedicated VPC with internet connectivity
  dmVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.12.14.0/24
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: DsSmallFilesNfsWorkshopVPC
  dmSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref 'dmVPC'
      CidrBlock: 10.12.14.0/24
      MapPublicIpOnLaunch: 'True'
      Tags:
      - Key: Name
        Value: DsSmallFilesNfsWorkshopSubnet1
  dmInternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Name
        Value: DsSmallFilesNfsWorkshopIGW
  dmAttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref 'dmVPC'
      InternetGatewayId: !Ref 'dmInternetGateway'
  dmRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref 'dmVPC'
      Tags:
      - Key: Name
        Value: DsSmallFilesNfsWorkshopRouteTable
  dmSubnet1RouteAssociaton:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref 'dmSubnet1'
      RouteTableId: !Ref 'dmRouteTable'
  dmRoutetoInternet:
    Type: AWS::EC2::Route
    DependsOn: dmInternetGateway
    Properties:
      RouteTableId: !Ref 'dmRouteTable'
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref 'dmInternetGateway'

  # We use the same security group for all four resources.  Technically port 80
  # isn't needed for the NFS server and the application server, but nothing is
  # listening on those ports on those servers.
  dmSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: DataSync Small Files NFS Workshop - Security Group for all resources
      VpcId: !Ref 'dmVPC'
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: '0.0.0.0/0'
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: '0.0.0.0/0'

  # We use this so we can limit access on this port to the SG
  dmSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      GroupId: !Ref 'dmSecurityGroup'
      IpProtocol: tcp
      ToPort: '2049'
      FromPort: '2049'
      SourceSecurityGroupId: !Ref 'dmSecurityGroup'
    DependsOn: dmSecurityGroup

  nfsServerInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref 'nfsServerIamRole'
  nfsServerIamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
  nfsServerRolePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
              - s3:GetObject
            Resource:
              - arn:aws:s3:::aws-datasync-samples/files/fs1m-small.tar
              - arn:aws:s3:::aws-datasync-samples/files/fs500k-small.tar
        Version: '2012-10-17'
      PolicyName: policy
      Roles:
        - !Ref 'nfsServerIamRole'
  nfsServer:
    Type: AWS::EC2::Instance
    CreationPolicy:
      ResourceSignal:
        Timeout: PT30M
        Count: 1
    Metadata:
      AWS::CloudFormation::Init:
        config:
          files:
            /opt/aws/cfn/initdata.sh:
              content: !Sub |
                #!/bin/bash
                mkdir -p /mnt/fs1 /mnt/fs2 /mnt/fs3
                devs=`lsblk | grep 200G | awk '{ print $1 }'`
                fsnum=1
                for d in $devs
                do
                  mkfs.xfs /dev/$d
                  mount /dev/$d /mnt/fs$fsnum
                  fsnum=$(( fsnum + 1 ))
                done
                chmod 777 /mnt/fs*
                aws s3 cp s3://aws-datasync-samples/files/fs500k-small.tar /mnt/fs1/fs500k-small.tar >> /dev/null
                aws s3 cp s3://aws-datasync-samples/files/fs500k-small.tar /mnt/fs2/fs500k-small.tar >> /dev/null
                aws s3 cp s3://aws-datasync-samples/files/fs1m-small.tar /mnt/fs3/fs1m-small.tar >> /dev/null
                cd /mnt/fs1/ && tar -xf fs500k-small.tar &
                cd /mnt/fs2/ && tar -xf fs500k-small.tar &
                cd /mnt/fs3/ && tar -xf fs1m-small.tar &
                wait
                rm -f /mnt/fs1/fs500k-small.tar /mnt/fs2/fs500k-small.tar /mnt/fs3/fs1m-small.tar
                echo READY > /home/ec2-user/datasets_ready
          commands:
            1-initData:
              command: "bash /opt/aws/cfn/initdata.sh"
            2-finishUp:
              command: !Sub "/opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackId} --resource nfsServer --region ${AWS::Region}"
    Properties:
      ImageId: !Ref linuxAmi
      InstanceType: c5.4xlarge
      IamInstanceProfile: !Ref 'nfsServerInstanceProfile'
      Tags:
        - Key: Name
          Value: !Join
            - ''
            - - NfsServer-
              - !Ref 'AWS::StackName'
      KeyName: !Ref 'kp'
      InstanceInitiatedShutdownBehavior: terminate
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: '8'
            DeleteOnTermination: 'true'
            VolumeType: gp2
        - DeviceName: /dev/xvdb
          Ebs:
            VolumeSize: '200'
            DeleteOnTermination: 'true'
            VolumeType: gp2
        - DeviceName: /dev/xvdc
          Ebs:
            VolumeSize: '200'
            DeleteOnTermination: 'true'
            VolumeType: gp2
        - DeviceName: /dev/xvdd
          Ebs:
            VolumeSize: '200'
            DeleteOnTermination: 'true'
            VolumeType: gp2
      NetworkInterfaces:
        - AssociatePublicIpAddress: 'true'
          DeviceIndex: '0'
          GroupSet:
            - !Ref 'dmSecurityGroup'
          SubnetId: !Ref 'dmSubnet1'
      UserData:
        Fn::Base64:
          !Sub |
            #!/bin/bash
            /opt/aws/bin/cfn-init -v -s ${AWS::StackId} -r nfsServer --region ${AWS::Region}

  dataSyncAgentInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref 'dataSyncAgentIamRole'
  dataSyncAgentIamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
        Version: '2012-10-17'
  dataSyncAgentRolePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Allow
            Action:
              - datasync:*
            Resource:
              - '*'
          - Effect: Allow
            Action:
              - iam:PassRole
            Resource:
              - '*'
        Version: '2012-10-17'
      PolicyName: policy
      Roles:
        - !Ref 'dataSyncAgentIamRole'

  dataSyncAgent1:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref dsAmi
      InstanceType: m5.2xlarge
      IamInstanceProfile: !Ref 'dataSyncAgentInstanceProfile'
      Tags:
        - Key: Name
          Value: !Join
            - ''
            - - DataSyncAgent1-
              - !Ref 'AWS::StackName'
      KeyName: !Ref 'kp'
      InstanceInitiatedShutdownBehavior: stop
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: '80'
            DeleteOnTermination: 'true'
            VolumeType: gp2
      NetworkInterfaces:
        - AssociatePublicIpAddress: 'true'
          DeviceIndex: '0'
          GroupSet:
            - !Ref 'dmSecurityGroup'
          SubnetId: !Ref 'dmSubnet1'

  dataSyncAgent2:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref dsAmi
      InstanceType: m5.2xlarge
      IamInstanceProfile: !Ref 'dataSyncAgentInstanceProfile'
      Tags:
        - Key: Name
          Value: !Join
            - ''
            - - DataSyncAgent2-
              - !Ref 'AWS::StackName'
      KeyName: !Ref 'kp'
      InstanceInitiatedShutdownBehavior: stop
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: '80'
            DeleteOnTermination: 'true'
            VolumeType: gp2
      NetworkInterfaces:
        - AssociatePublicIpAddress: 'true'
          DeviceIndex: '0'
          GroupSet:
            - !Ref 'dmSecurityGroup'
          SubnetId: !Ref 'dmSubnet1'

Outputs:
  nfsServerPrivateIP:
    Description: NFS Server Private IP Address
    Value: !GetAtt nfsServer.PrivateIp
  dataSyncAgent1PublicIP:
    Description: DataSync Agent 1 - Public IP Address
    Value: !GetAtt dataSyncAgent1.PublicIp
  dataSyncAgent1PrivateIP:
    Description: DataSync Agent 1 - Private IP Address
    Value: !GetAtt dataSyncAgent1.PrivateIp
  dataSyncAgent2PublicIP:
    Description: DataSync Agent 2 - Public IP Address
    Value: !GetAtt dataSyncAgent2.PublicIp
  dataSyncAgent2PrivateIP:
    Description: DataSync Agent 2 - Private IP Address
    Value: !GetAtt dataSyncAgent2.PrivateIp

Các resource tạo ra:

dataSyncAgentRolePolicy    Milli-dataS-13mx4FFXAC7w    AWS::IAM::Policy    

dmAttachGateway    IGW|vpc-07ce8d594e1a5b98c    AWS::EC2::VPCGatewayAttachment    

dmInternetGateway    igw-0ba4a47eb3ecbab09 AWS::EC2::InternetGateway    

dmRouteTable    rtb-0698bd8773c9ee951    AWS::EC2::RouteTable    

dmRoutetoInternet    rtb-0698bd8773c9ee951|0.0.0.0/0    AWS::EC2::Route    

dmSecurityGroup    sg-034904fd670bc1406  AWS::EC2::SecurityGroup    

dmSecurityGroupIngress    dmSecurityGroupIngress    AWS::EC2::SecurityGroupIngress    

dmSubnet1    subnet-021e99f4eb84019db  AWS::EC2::Subnet    

dmSubnet1RouteAssociaton    rtbassoc-0a040a01b1d1e1058    AWS::EC2::SubnetRouteTableAssociation    

dmVPC    vpc-07ce8d594e1a5b98c  AWS::EC2::VPC    

nfsServer    i-0ee47a0f96d75980f  AWS::EC2::Instance    

nfsServerIamRole    MillionFiles-OnPrem-nfsServerIamRole-AsJCV91pxRHL  AWS::IAM::Role    

nfsServerInstanceProfile    MillionFiles-OnPrem-nfsServerInstanceProfile-JlQlNNCBgmUV    AWS::IAM::InstanceProfile    

nfsServerRolePolicy    Milli-nfsSe-OIyzaK0zaaUH    AWS::IAM::Policy

Outputs:

Cloudformation template in cloud

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS DataSync Workshop - NFS Small Files Migration - In-Cloud Region
Metadata:
  License:
    Description: |
      Copyright 2019-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.

      Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify,
      merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so.

      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Resources:

  # We use the GUID from the ARN of the stack ID to generate
  # a unique bucket name
  s3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True
      BucketName: !Join
      - "-"
      - - "million-files-nfs"
        - !Select
          - 2
          - !Split
            - "/"
            - !Ref "AWS::StackId"

  # Give the role a friendly name as the workshop user will need to
  # reference it when creating DataSync tasks.
  s3BucketIamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - sts:AssumeRole
            Effect: Allow
            Principal:
              Service:
                - datasync.amazonaws.com
        Version: '2012-10-17'
  s3BucketRolePolicy:
    Type: AWS::IAM::Policy
    DependsOn: s3Bucket
    Properties:
      PolicyDocument:
        Statement:
          - Effect: Allow
            Resource: !GetAtt s3Bucket.Arn
            Action:
              - s3:GetBucketLocation
              - s3:ListBucket
              - s3:ListBucketMultipartUploads
              - s3:HeadBucket
          - Effect: Allow
            Resource: !Join [ "/", [ !GetAtt s3Bucket.Arn, "*" ] ]
            Action:
              - s3:AbortMultipartUpload
              - s3:DeleteObject
              - s3:GetObject
              - s3:ListMultipartUploadParts
              - s3:PutObject
        Version: '2012-10-17'
      PolicyName: policy
      Roles:
        - !Ref 's3BucketIamRole'

  dataSyncLogs:
    Type: AWS::Logs::LogGroup
    Properties:
      RetentionInDays: 3
      LogGroupName: !Join
        - ''
        - - DataSyncLogs-
          - !Ref 'AWS::StackName'

Outputs:
  bucketName:
    Description: S3 Bucket Name
    Value: !Ref 's3Bucket'
  bucketRoleForDataSync:
    Description: S3 Bucket Role for DataSync
    Value: !Ref 's3BucketIamRole'
dataSyncLogs    DataSyncLogs-MillionFiles-InCloud  AWS::Logs::LogGroup    

s3Bucket    million-files-nfs-4ee43070-7f76-11ee-a78b-0a82928f53af  AWS::S3::Bucket    

s3BucketIamRole    MillionFiles-InCloud-s3BucketIamRole-hHjVDkRAXLsf  AWS::IAM::Role    

s3BucketRolePolicy    Milli-s3Buc-EnOIcbgDSWqE    AWS::IAM::Policy

Configure NFS server & activate agent

Configure NFS server

Tại region đại diện cho on premises, connect vào NFS EC2 instance và chạy lệnh kiểm tra các files, mount points:

[ec2-user@ ~]$ mount | grep /mnt

  /dev/nvme1n1 on /mnt/fs1 type xfs (rw,relatime,attr2,inode64,noquota)
  /dev/nvme2n1 on /mnt/fs2 type xfs (rw,relatime,attr2,inode64,noquota)
  /dev/nvme3n1 on /mnt/fs3 type xfs (rw,relatime,attr2,inode64,noquota)

3 file system được mount ở thư mục /mnt, kiểm tra dung lượng:

[ec2-user@ ~]$ df -h | grep /mnt

  /dev/nvme1n1    200G   12G  189G   6% /mnt/fs1
  /dev/nvme2n1    200G   12G  189G   6% /mnt/fs2
  /dev/nvme3n1    200G   22G  179G  11% /mnt/fs3

Kiểm tra số lượng file và directory:

  [ec2-user@ ~]$ cd /mnt
  [ec2-user@ ~]$ ls -R fs1/ | wc -l
  [ec2-user@ ~]$ ls -R fs2/ | wc -l
  [ec2-user@ ~]$ ls -R fs3/ | wc -l

Xem cách các file được tổ chức:

[ec2-user@ ~]$ ls fs1
[ec2-user@ ~]$ ls fs1/d0001
[ec2-user@ ~]$ ls -a fs1/d0001/dir0001

Các lệnh này cho thấy có 50 thư mục trong fs1, mỗi thư mục chứa 20 thư mục con. Mỗi thư mục con chứa 500 tệp cùng với ba tệp bổ sung: .htaccess, index.html,Manifest.lst. Các hệ thống tệp khác cũng tương tự, ngoại trừ việc fs3 có 100 thư mục cấp cao nhất, thay vì 50. Bạn sẽ sao chép tất cả các tệp và thư mục vào bộ chứa S3 của mình ngoại trừ .htaccess và index.html.

Bạn muốn chuyển dữ liệu từ cả ba hệ thống tệp bằng DataSync. Để làm như vậy, bạn sẽ cần tạo ba NFS exports (aka file shares). Bạn thực hiện việc này bằng cách sửa đổi tệp /etc/exports:

Trên máy chủ NFS, thêm ba dòng sau vào tệp /etc/exports. Bạn sẽ cần sửa đổi tệp dưới dạng root, vì vậy hãy sử dụng lệnh sudo khi khởi động trình soạn thảo của bạn.

/mnt/fs1 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs2 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs3 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)

Thay thế các địa chỉ IP ở trên bằng địa chỉ IP private tương ứng được chỉ định cho các EC2 instance cho từng DataSync agent, như được báo cáo trong Output CloudFormation cho khu vực ON-PREMISES.

Docs tham khảo: https://docs.aws.amazon.com/datasync/latest/userguide/create-nfs-location.html#accessing-nfs-configuring-export

Chạy lệnh sau để khởi động lại máy chủ NFS và áp dụng export settings:

[ec2-user@ ~]$ sudo systemctl restart nfs

Chạy lệnh sau để xác minh rằng ba file systems chỉ được xuất sang DataSync agent:

[ec2-user@ ~]$ showmount -e

/mnt/fs3 10.12.14.16,10.12.14.99
/mnt/fs2 10.12.14.16,10.12.14.99
/mnt/fs1 10.12.14.16,10.12.14.99

Để cho phép các DataSync agent truy cập vào máy chủ NFS, bạn đã tạo các NFS exports cho ba file share. Trong lab này, các agents không cần phải ghi bất cứ điều gì vào file system, vì vậy bạn đã định cấu hình mỗi lần export ở chế độ chỉ đọc bằng cách sử dụng cờ ‘ro’ trong tệp /etc/exports. Ngoài ra, DataSync agent sẽ gắn các NFS exports với tư cách là người dùng root, do đó bạn cũng chỉ định cờ ‘no_root_squash’ để đảm bảo agent có toàn quyền truy cập vào tất cả dữ liệu trên hệ thống tệp. Cuối cùng, bạn chỉ export file system sang DataSync agent để khóa quyền truy cập.

Activate agent

  • Chuyển sang region in cloud.

  • Tạo agent với Service endpoint là “Public service endpoints”.

  • Trong phần Activation key, nhập địa chỉ IP public của DataSync agent đầu tiên đang chạy trong khu vực in cloud. Bạn sử dụng địa chỉ IP public ở đây vì tác nhân cần có thể truy cập được bằng trình duyệt web của bạn để kích hoạt. Nhập địa chỉ IP của agent như hình bên dưới rồi nhấn Get key.

Khi được activate thành công, sẽ có activate key được trả về như sau:

Successfully retrieved activation key from agent
Activation key
075CB-74QPS-TH6DC-KPBJE-RD8SF
Agent address
3.133.137.15

Nhập tên agent (”Agent 1″ hoặc “Agent 2”) và áp dụng bất kỳ tag nào nếu muốn, sau đó nhấp vào Create agent. Lặp lại các bước trên cho agent thứ hai. Với cả hai agent được tạo, bạn sẽ thấy hai agent được liệt kê trong bảng điều khiển DataSync, như hiển thị bên dưới:

Chạy thử test transfer để validate network và performance

Ở region in cloud:

Tạo datasync task mới với các tuỳ chọn như sau:

  • Create a new location và chọn Location type select Network File System (NFS) từ dropdown

  • Bạn sẽ sử dụng cả agent cho task này, vì vậy hãy chọn cả hai agent đã tạo.

  • Nhập địa chỉ IP private của NFS server, theo kết quả đầu ra của CloudFormation trong vùng ON-PREMISES. Đây là địa chỉ IP mà DataSync agent sẽ sử dụng để mount NFS server.

  • Mount path: nhập /mnt/fs1/d0001. Điều này sẽ chỉ sao chép các tập tin từ thư mục ‘d0001’ trên fs1.

  • Chọn Next

  • Bây giờ bạn sẽ destination location. Đảm bảo đã chọn Create a new location và đối với Location type, hãy chọn Amazon S3 bucket S3 từ dropdown.

  • S3 storage class: Standard

  • Folder: Nhập /fs1/d0001. Thao tác này sẽ đặt tất cả các tệp được chuyển vào thư mục này và cung cấp một nơi để sao chép các tệp trong tương lai.

  • IAM role: Chọn role có tên bắt đầu là MillionFiles-inCloud. Role này cung cấp cho dịch vụ DataSync các quyền cần thiết để ghi dữ liệu vào bộ chứa S3.

  • Chọn Next

  • Đặt tên cho task là Test Task.

  • Trong phần Task execution configuration, đảm bảo đã chọn Verify only the data transferred trong phần Verify data. Điều này sẽ xác minh rằng mọi byte của mọi tệp được truyền đều được ghi thành công vào đích.

  • Giữ nguyên tất cả các tùy chọn khác

  • Trong phần Data transfer configuration, cho mục Exclude patterns, chọn nú Add Pattern và nhập */.htaccess. Lặp lại thao tác này và nhập /index.html. Điều này sẽ ngăn tác vụ sao chép hai tệp này từ bất kỳ thư mục nào trên hệ thống tệp nguồn.

  • Cuộn xuống phần Task logging và chọn DataSyncLogs-MillionFiles-InCloud log group

  • Chọn Next

  • Chọn Create task.

  • Run task

Khi task chạy, trạng thái thực thi sẽ chuyển từ “Launching” sang “Preparing” sang “Transferring” sang “Verifying” và cuối cùng là “Success”. Quá trình thực hiện task sẽ báo cáo số liệu thống kê về công việc như hình dưới đây. Sẽ mất vài phút để hoàn thành task. Sau khi tác vụ hoàn tất, hãy lưu ý rằng 10.041 tệp đã được chuyển. Điều này bao gồm 20 thư mục con trong d0001, mỗi thư mục chứa 500 tệp, cùng với tệp kê khai.lst trong mỗi thư mục con, cùng với một đối tượng trong S3 cho chính các thư mục đó, bao gồm cả chính thư mục d0001.

Từ bảng điều khiển quản lý AWS, chọn Dịch vụ rồi chọn S3. Trong danh sách bucket, nhấp vào bucket bắt đầu bằng Million-files-nfs. Bạn sẽ thấy thư mục cấp cao nhất fs1, bên trong là thư mục d0001. Bên trong thư mục này sẽ có 20 thư mục con chứa các file đã được sao chép, trong đó có fileManifest.lst cho mỗi thư mục con. Xác minh rằng các tệp .htaccess và index.html không được sao chép.

Để biết thêm thông tin về kết quả thực thi task, hãy chạy các lệnh sau, thay thế ID thực thi bằng ID thực thi ở đầu trang bảng điều khiển DataSync (như được hiển thị ở trên). Ngoài ra, hãy thay thế tham số – -zone bằng vùng IN-CLOUD của bạn:

Sử dụng lệnh “list-task-executions” để nhận ARN đầy đủ của quá trình thực thi tác vụ, sau đó được chuyển tới lệnh “describe-task-executions”.

~$ aws datasync list-task-executions --region us-east-2 | grep exec-087e8a24374165fa2
"TaskExecutionArn": "arn:aws:datasync:us-east-2:--:task/task-0409cb63be00594d2/execution/exec-087e8a24374165fa2",

~$ aws datasync describe-task-execution --region us-east-2 --task-execution-arn arn:aws:datasync:us-east-2:--:task/task-0409cb63be00594d2/execution/exec-087e8a24374165fa2

Output sẽ có dạng như sau:

{
    "TaskExecutionArn": "arn:aws:datasync:us-east-2:--:task/task-0409cb63be00594d2/execution/exec-087e8a24374165fa2",
    "Status": "SUCCESS",
    "Options": {
        "VerifyMode": "ONLY_FILES_TRANSFERRED",
        "OverwriteMode": "ALWAYS",
        "Atime": "BEST_EFFORT",
        "Mtime": "PRESERVE",
        "Uid": "INT_VALUE",
        "Gid": "INT_VALUE",
        "PreserveDeletedFiles": "PRESERVE",
        "PreserveDevices": "NONE",
        "PosixPermissions": "PRESERVE",
        "BytesPerSecond": -1,
        "TaskQueueing": "ENABLED"
    },
    "Excludes": [
        {
            "FilterType": "SIMPLE_PATTERN",
            "Value": "*/.htaccess|*/index.html"
        }
    ],
    "Includes": [],
    "StartTime": 1578092083.501,
    "EstimatedFilesToTransfer": 10041,
    "EstimatedBytesToTransfer": 204188279,
    "FilesTransferred": 10041,
    "BytesWritten": 204188279,
    "BytesTransferred": 204188279,
    "Result": {
        "PrepareDuration": 3447,
        "PrepareStatus": "SUCCESS",
        "TotalDuration": 91639,
        "TransferDuration": 77060,
        "TransferStatus": "SUCCESS",
        "VerifyDuration": 13459,
        "VerifyStatus": "SUCCESS"
    }
}

Điểm mấu chốt từ đầu ra lệnh là thời gian thực hiện tác vụ trong các giai đoạn chuẩn bị, chuyển giao và xác minh (lần lượt là PrepareDuration, TransferDuration và VerifyDuration). Các con số được tính bằng mili giây, do đó, bạn có thể thấy từ kết quả đầu ra ở trên rằng tác vụ đã mất 3,4 giây trong giai đoạn chuẩn bị, 77 giây trong giai đoạn chuyển giao và 13,4 giây trong giai đoạn xác minh.

Chạy full transfer

1. Tạo task cho fs1

  1. Đi đến DataSync console ở IN-CLOUD region, click Tasks ở navigation pane và chọn Create task.

  2. Sử dụng seting như sau cho source location:

    • Location type: Network File System (NFS)

    • Agents: Agent 1

    • NFS Server: địa chỉ IP private của NFS server

    • Mount path: /mnt/fs1

  3. Click Next.

  4. Sử dụng setting như sau cho destination location:

    • Location type: Amazon S3 bucket

    • S3 bucket: chọn bucket bắt đầu bằng million_files_nfs

    • S3 storage class: Standard

    • Folder: /fs1

    • IAM role: chọn role bắt đầu bằng MillionFiles-inCloud

  5. Click Next.

  6. Đặt tên task là Copy FS1.

  7. Đặt tuỳ chọn Verify data là Verify only the data transferred.

  8. Thêm 2 exclude patterns: /.htaccess and /index.html

  9. Trong Task logging, chọn DataSyncLogs-MillionFiles-InCloud log group.

  10. Click Next.

  11. Click Create task.

2. Tạo task cho fs2

  1. Chọn Create task.

  2. Sử dụng seting như sau cho source location:

    • Location type: Network File System (NFS)

    • Agents: Agent 1

    • NFS Server: Private IP address của NFS server

    • Mount path: /mnt/fs2

  3. Click Next.

  4. Sử dụng setting như sau cho destination location:

    • Location type: Amazon S3 bucket

    • S3 bucket: chọn bucket bắt đầu bằng million_files_nfs

    • S3 storage class: Standard

    • Folder: /fs2

    • IAM role: chọn role bắt đầu bằng MillionFiles-inCloud

  5. Click Next.

  6. Đặt tên task là Copy FS2.

  7. Đặt tuỳ chọn Verify data là Verify only the data transferred.

  8. Đảm bảo rằng Queueing được set là Enabled.

  9. Thêm 2 exclude patterns: /.htaccess and /index.html

  10. Trong Task logging, chọn DataSyncLogs-MillionFiles-InCloud log group.

  11. Click Next.

  12. Click Create task.


3. Tạo task cho fs3

  1. Create task.

  2. Sử dụng seting như sau cho source location:

    • Location type: Network File System (NFS)

    • Agents: Agent 2

    • NFS Server: Private IP address của NFS server

    • Mount path: /mnt/fs3

  3. Click Next.

  4. Sử dụng setting như sau cho destination location:

    • Location type: Amazon S3 bucket

    • S3 bucket: chọn bucket bắt đầu bằng million_files_nfs

    • S3 storage class: Standard

    • Folder: /fs3

    • IAM role: chọn role bắt đầu bằng MillionFiles-inCloud

  5. Click Next.

  6. Đặt tên task là Copy FS3.

  7. Đặt tuỳ chọn Verify data là Verify only the data transferred.

  8. Thêm 2 exclude patterns: /.htaccess and /index.html

  9. Trong Task logging, chọn DataSyncLogs-MillionFiles-InCloud log group.

  10. Click Next.

  11. Click Create task.

Bây giờ bạn sẽ có tổng cộng bốn task – taskkiểm tra từ trước và ba task bạn vừa tạo.

  1. Start task

    • Đợi ba task chuyển từ “Creating” sang “Available”.

    • Start task cho fs1 trước, tiếp theo là task cho fs2 và cuối cùng là task cho fs3.

    • Lưu ý rằng task cho fs2 sẽ ngay lập tức chuyển sang trạng thái Queued. Điều này là do các tác vụ cho fs1 và fs2 sử dụng cùng một agent (Agent 1) và tác nhân DataSync chỉ có thể thực thi một tác vụ tại một thời điểm.

Sau khi tác vụ fs1 hoàn thành, tác vụ fs2 sẽ tự động được chạy.

Trong môi trường sản xuất, điều quan trọng là phải giám sát tất cả các tài nguyên để đảm bảo quá trình truyền DataSync diễn ra như mong đợi. Điều này bao gồm việc giám sát không chỉ các tác vụ DataSync mà còn cả máy chủ và mạng NFS. Hiệu suất kém trên bộ lưu trữ nguồn hoặc các sự cố mạng như mất gói hoặc truyền lại TCP có thể làm giảm đáng kể hiệu suất của DataSync.

Trong khi thực hiện ba nhiệm vụ, hãy sử dụng CloudWatch để khám phá các số liệu khác nhau có sẵn cho cả tổng đài viên và nhiệm vụ.

Sẽ mất khoảng 20 phút để hoàn thành tất cả các nhiệm vụ.

Sau khi tất cả tác vụ đã được thực thi thành công, hãy kiểm tra vùng lưu trữ S3. Bây giờ bạn sẽ thấy ba thư mục cấp cao nhất: fs1, fs2 và fs3 (bạn có thể cần làm mới nhóm).

So sánh kết quả thực hiện tác vụ của fs1 với fs2. Đối với tác vụ fs1, bạn sẽ thấy 492.010 tệp được chuyển, trong khi đối với tác vụ fs2, bạn sẽ thấy 502.051 tệp được chuyển. Cả hai hệ thống tệp đều có cùng số lượng tệp, vậy tại sao lại có sự khác biệt?

Hãy nhớ rằng khi chạy tác vụ kiểm tra trong mô-đun 4, bạn đã sao chép một thư mục cấp cao nhất từ fs1 – tổng cộng 10.041 tệp và thư mục. Vì những tệp đó đã được sao chép một lần nên DataSync biết rằng chúng không cần phải sao chép lại và chúng đã bị bỏ qua trong quá trình thực hiện tác vụ fs1. DataSync đã đưa ra quyết định này trong giai đoạn Chuẩn bị của tác vụ, khi nó so sánh các tệp trong nguồn với các tệp ở đích và tìm thấy một số tệp đã có trong nhóm.

Tổng cộng, qua bốn tác vụ, bạn đã chuyển và xác minh 2.008.203 tệp trong khoảng 25 phút.

Thực hiện sao chép dữ liệu incremental

Bây giờ sẽ thực hiện thay đổi dữ liệu trong NFS server. Để cập nhật dữ liệu được sao chép, chúng ta sẽ chạy lại task.

  • Thay đổi trên NFS server:
[ec2-user@ ~]$ cd /mnt/fs2/d0001/dir0001
[ec2-user@ ~]$ dd if=/dev/urandom of=newfile1 bs=1M count=1
[ec2-user@ ~]$ echo "newfile1" >> manifest.lst

Các lệnh trên sẽ tạo một tệp mới trên fs2 có tên “newfile1” và nối thêm một mục nhập cho tệp mới vào cuối tệp kê khai.lst trong thư mục cục bộ. Điều này có nghĩa là bây giờ bạn có một tệp mới trên fs2 và một tệp đã được sửa đổi.

Để cập nhật vùng lưu trữ S3 với những thay đổi bạn đã thực hiện đối với fs2, bạn chỉ cần chạy lại tác vụ có tên Sao chép FS2 mà bạn đã tạo. Vị trí nguồn và đích giống nhau và bạn sẽ giữ nguyên cài đặt tác vụ như đã sử dụng trước đó.

  1. Vào console IN-CLOUD region, click Tasks trong phần navigation pane, chọn task Copy FS2.

  2. Click Start.

  3. Click vào History tab – bây giờ bạn sẽ thấy hai lần thực thi tác vụ, một cho tác vụ được thực hiện trong bước trước và tác vụ bạn vừa khởi chạy:

Khi tác vụ hoàn thành, bạn sẽ thấy 3 tệp đã được truyền và tổng dữ liệu được truyền là 1 MiB. Ba tệp này là tệp mới được tạo ở trên (có kích thước 1 MiB), tệp manifest.lst đã được sửa đổi và sau đó là đối tượng trong nhóm S3 đại diện cho thư mục dir0001, cần được cập nhật vì một tệp mới đã bị xóa.

So sánh thời gian chạy:

~$ aws datasync list-task-executions --region us-east-2 | grep exec-07e667d3c41fa8341
     "TaskExecutionArn": "arn:aws:datasync:us-east-2:--:task/task-00007d923f4357143/execution/exec-07e667d3c41fa8341",

  ~$ aws datasync describe-task-execution --region us-east-2 --task-execution-arn arn:aws:datasync:us-east-2:--:task/task-00007d923f4357143/execution/exec-07e667d3c41fa8341
  {
      "TaskExecutionArn": "arn:aws:datasync:us-east-2:--:task/task-00007d923f4357143/execution/exec-07e667d3c41fa8341",
      "Status": "SUCCESS",
      "Options": {
          "VerifyMode": "ONLY_FILES_TRANSFERRED",
          "OverwriteMode": "ALWAYS",
          "Atime": "BEST_EFFORT",
          "Mtime": "PRESERVE",
          "Uid": "INT_VALUE",
          "Gid": "INT_VALUE",
          "PreserveDeletedFiles": "PRESERVE",
          "PreserveDevices": "NONE",
          "PosixPermissions": "PRESERVE",
          "BytesPerSecond": -1,
          "TaskQueueing": "ENABLED"
      },
      "Excludes": [
          {
              "FilterType": "SIMPLE_PATTERN",
              "Value": "*/.htaccess|*/index.html"
          }
      ],
      "Includes": [],
      "StartTime": 1578611450.582,
      "EstimatedFilesToTransfer": 3,
      "EstimatedBytesToTransfer": 1053085,
      "FilesTransferred": 3,
      "BytesWritten": 1053085,
      "BytesTransferred": 1053085,
      "Result": {
          "PrepareDuration": 126943,
          "PrepareStatus": "SUCCESS",
          "TotalDuration": 199632,
          "TransferDuration": 71423,
          "TransferStatus": "SUCCESS",
          "VerifyDuration": 2467,
          "VerifyStatus": "SUCCESS"
      }
  }

Ở phần trên, bạn có thể thấy rằng tác vụ tiêu tốn khoảng 127 giây trong giai đoạn chuẩn bị. Lặp lại các lệnh trên nhưng sử dụng ID để thực hiện tác vụ trước đó. Nhiệm vụ đầu tiên của bạn cho fs2 đã tiêu tốn bao nhiêu thời gian trong giai đoạn chuẩn bị?

Bạn có thể sẽ thấy sự khác biệt đáng kể về thời gian dành cho giai đoạn chuẩn bị. Trong khi lần thực hiện đầu tiên chỉ mất vài giây để chuẩn bị thì lần thực hiện thứ hai mất vài phút. Tại sao lại có sự khác biệt?

Khi bạn thực thi tác vụ sao chép fs2 lần đầu tiên, không có đối tượng nào trong nhóm S3 trong thư mục /fs2, do đó không có gì để so sánh giữa nguồn và đích. Tuy nhiên, với lần thực thi thứ hai, hiện có hơn 500.000 đối tượng trong nhóm S3 dành cho fs2 cần được so sánh với nguồn. Việc so sánh tất cả các tệp đó có thể mất một lúc – trong trường hợp này là vài phút.

Có cách nào để giảm thời gian này?

Tiếp tục với incremental data

Một cách để giảm lượng thời gian cần thiết cho việc chuẩn bị tệp là giới hạn phạm vi của các tệp được so sánh. Bạn có thể thực hiện việc này bằng cách tạo tác vụ mới với vị trí nguồn chính xác hơn, nhưng điều đó có nghĩa là sao chép tất cả cài đặt của bạn sang tác vụ mới và có nguy cơ thiếu cài đặt cấu hình. Một tùy chọn khác là sử dụng các bộ lọc bao gồm cấp độ nhiệm vụ.

Trước khi thực hiện lần chạy khác, hãy tạo thêm thay đổi trong thư mục dir0001 fs2. Chạy các lệnh sau:

[ec2-user@ ~]$ cd /mnt/fs2/d0001/dir0001
[ec2-user@ ~]$ dd if=/dev/urandom of=newfile2 bs=1M count=1
[ec2-user@ ~]$ echo "newfile2" >> manifest.lst

Chạy lại task. Tuy nhiên lần này chọn Start with overriding options, trong phần Data transfer configuration chọn Specific files and folders

Tại đây, bạn có tùy chọn cung cấp một hoặc nhiều include pattern, tương tự như các pattern bạn đã chỉ định trước đó để loại trừ các tệp .htaccess và index.html. Nhưng trong trường hợp này, bạn đang thông báo cho tác vụ DataSync những tệp và thư mục nào cần bao gồm một cách rõ ràng, bỏ qua mọi thứ khác.

Nhập pattern /d0001/dir0001/* rồi nhấp vào nút Start.

Sau khi tác vụ hoàn tất quá trình thực thi, hãy quay lại vùng lưu trữ S3 của bạn và xác minh rằng bạn thấy tệp mới mới nhất, newfile2, cũng như dấu thời gian được cập nhật cho tệp kê khai.lst.

Chạy lại lệnh mô tả-thực thi tác vụ, với id thực thi tác vụ mới nhất, để biết thời lượng cho giai đoạn chuẩn bị. Điều này so với lần thực hiện trước đó như thế nào?

Bạn sẽ thấy thời gian chuẩn bị đã giảm đáng kể. Điều này là do tác vụ DataSync chỉ quét các tệp trong thư mục /d0001/dir0001/, chỉ có khoảng 500 tệp. Bằng cách sử dụng các bộ lọc bao gồm, bạn có thể giảm đáng kể phạm vi của tác vụ DataSync mà không cần phải tạo tác vụ mới.

Chỉnh sửa để làm chiều ngược lại: S3 to NFS

Giả sử giờ sẽ copy file từ tư mục /d0001/dir0001/ và fs3. Nếu cứ để nguyên setting, chỉ thay source – destination sẽ lỗi:

Do đó ta cần chỉnh sửa trong nfs server

Trước:

/mnt/fs1 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs2 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs3 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs1 10.12.14.240(ro,no_root_squash) 10.12.14.221(ro,no_root_squash)
/mnt/fs2 10.12.14.240(ro,no_root_squash) 10.12.14.221(ro,no_root_squash)
/mnt/fs3 10.12.14.240(ro,no_root_squash) 10.12.14.221(ro,no_root_squash)

Sau:

/mnt/fs1 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs2 10.12.14.240(ro,no_root_squash) 10.12.14.101(ro,no_root_squash)
/mnt/fs3 10.12.14.240(rw,no_root_squash) 10.12.14.101(rw,no_root_squash)
/mnt/fs1 10.12.14.240(ro,no_root_squash) 10.12.14.221(ro,no_root_squash)
/mnt/fs2 10.12.14.240(ro,no_root_squash) 10.12.14.221(ro,no_root_squash)
/mnt/fs3 10.12.14.240(rw,no_root_squash) 10.12.14.221(rw,no_root_squash)
[ec2-user@ ~]$ sudo systemctl restart nfs

Kết quả: