

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 開始使用 Amazon RDS 零 ETL 整合
<a name="zero-etl.setting-up"></a>

在建立零 ETL 整合之前，請先使用必要的參數和許可設定 RDS 資料庫和資料倉儲。安裝期間，您將完成以下步驟：

1. [建立自訂資料庫參數群組。](#zero-etl.parameters)

1. [建立來源資料庫](#zero-etl.create-cluster)。

1. [為 Amazon Redshift 建立目標資料倉儲](#zero-etl-setting-up.data-warehouse)或[建立目標 Amazon SageMaker Lakehouse](#zero-etl-setting-up.sagemaker)。

完成這些任務後，請繼續 [建立與 Amazon Redshift 的 Amazon RDS 零 ETL 整合](zero-etl.creating.md) 或 [建立與 Amazon SageMaker 資料湖倉的 Amazon RDS 零 ETL 整合](zero-etl.creating-smlh.md)。

**提示**  
您可以在建立整合時讓 RDS 為您完成這些設定步驟，而不用手動執行這些步驟。若要立即開始建立整合，請參閱 [建立與 Amazon Redshift 的 Amazon RDS 零 ETL 整合](zero-etl.creating.md)。

對於步驟 3，您可以選擇根據您的需求建立目標資料倉儲 (步驟 3a) 或目標湖房 (步驟 3b)：
+ 如果您需要使用 SQL 型分析的傳統資料倉儲功能，請選擇資料倉儲。
+ 如果您需要機器學習功能，並想要將湖房功能用於資料科學和 ML 工作流程，請選擇 Amazon SageMaker Lakehouse。

## 步驟 1：建立自訂資料庫參數群組。
<a name="zero-etl.parameters"></a>

Amazon RDS 零 ETL 整合需要控制資料複寫之資料庫參數的特定值。特定參數取決於您的來源資料庫引擎。若要設定這些參數，您必須先建立自訂資料庫參數群組，然後將其與來源資料庫建立關聯。根據您的來源資料庫引擎設定下列參數值。如需建立參數群組的指示，請參閱 [Amazon RDS 資料庫執行個體的資料庫參數群組](USER_WorkingWithDBInstanceParamGroups.md)。建議您在相同的要求中設定所有參數值，以避免相依性問題。

**RDS for MySQL**：
+ `binlog_format=ROW`
+ `binlog_row_image=full`

此外，請確定`binlog_row_value_options` 參數*未*設定為 `PARTIAL_JSON`。如果來源資料庫是多可用區域資料庫叢集，請確定 `binlog_transaction_compression` 參數*未*設定為 `ON`。

其中一些參數 (例如 `binlog_format`) 是動態的，這表示您可以對參數套用變更，而無需觸發重新啟動。這表示某些現有的工作階段可能會繼續使用參數的舊值。若要避免在建立零 ETL 整合時造成問題，請啟用[效能結構描述](USER_PerfInsights.EnableMySQL.md)。效能結構描述可確保零 ETL 預先檢查執行，這有助於儘早偵測到程序中缺少的參數。

**RDS for PostgreSQL**：
+ `rds.logical_replication = 1`
+ `rds.replica_identity_full = 1`
+ `session_replication_role = origin`
+ `wal_sender_timeout ≥ 20000 or = 0`
+ `max_wal_senders ≥ 20`
+ `max_replication_slots ≥ 20`

對於多個 PostgreSQL 整合，每個整合將使用一個邏輯複寫槽。根據您的用量檢閱 `max_replication_slots` 和 `max_wal_senders` 參數。

為了在零 ETL 整合中有效率地同步資料，請在來源資料庫執行個體中設定 `rds.replica_identity_full`。這會指示資料庫在 `UPDATE` 和 `DELETE` 操作期間，在預寫日誌 (WAL) 中[記錄完整的資料列資料](https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY)，而不只是主索引鍵資訊。即使所有複寫的資料表都需要主索引鍵，零 ETL 也需要完整的資料列資料。為了判斷查詢期間可以看到哪些資料， Amazon Redshift 會使用專門的反聯結策略來比較您的資料與內部刪除追蹤資料表。記錄完整資料列影像有助於 Amazon Redshift 有效率地執行這些反聯結。如果沒有完整的資料列資料，Amazon Redshift 將需要執行額外的查詢，這可能在 Amazon Redshift 所使用的單欄式引擎進行高輸送量操作期間導致效能下降。

**重要**  
將複本身分設定為記錄完整資料列[會增加您的 WAL 磁碟區](https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL)，這可能會導致更高的寫入放大和 I/O 用量，尤其是對於寬資料表或頻繁更新。若要為這些影響做好準備，請規劃您的儲存容量和 I/O 要求、監控 WAL 成長，以及追蹤大量寫入工作負載中的複寫延遲。

**RDS for Oracle**：

RDS for Oracle 不需要參數變更。

## 步驟 2：選取或建立來源資料庫
<a name="zero-etl.create-cluster"></a>

在建立自訂資料庫參數群組之後，請選擇或建立 RDS 資料庫執行個體 。此資料庫將是複寫至目標資料倉儲之資料的來源。如需建立單一可用區或多可用區域資料庫執行個體的指示，請參閱 [建立 Amazon RDS 資料庫執行個體](USER_CreateDBInstance.md)。如需建立多可用區域資料庫叢集的指示 （僅限 MySQL 的 RDS)，請參閱 [為 Amazon RDS 建立多可用區域資料庫叢集](create-multi-az-db-cluster.md)。

資料庫必須執行支援的資料庫引擎版本。如需支援的版本的清單，請參閱[Amazon RDS 零 ETL 整合的支援區域和資料庫引擎](Concepts.RDS_Fea_Regions_DB-eng.Feature.ZeroETL.md)。

當您建立資料庫時，在**其他組態**下，將預設**資料庫參數群組**變更為您在上一個步驟中建立的自訂參數群組。

**注意**  
如果您在已建立資料庫*之後*將參數群組與資料庫建立關聯，則必須將資料庫重新開機以套用變更，然後才能建立零 ETL 整合。如需相關指示，請參閱 [在資料庫執行個體](USER_RebootInstance.md) 或 [重新啟動 Amazon RDS 的多可用區域資料庫叢集和讀取器資料庫執行個體](multi-az-db-clusters-concepts-rebooting.md)。

此外，請確定已在資料庫上啟用自動備份。如需詳細資訊，請參閱[啟用自動備份](USER_WorkingWithAutomatedBackups.Enabling.md)。

## 步驟 3a：建立目標資料倉儲
<a name="zero-etl-setting-up.data-warehouse"></a>

在建立來源資料庫之後，您必須建立並設定目標資料倉儲。資料倉儲必須符合下列需求：
+ 使用具有至少兩個節點的 RA3 節點類型，或 Redshift Serverless。
+ 已加密 (如果使用已佈建的叢集)。如需詳細資訊，請參閱 [Amazon Redshift 資料庫加密](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-db-encryption.html)。

如需建立資料倉儲的指示，請參閱[建立叢集](https://docs.aws.amazon.com/redshift/latest/mgmt/create-cluster) (適用於佈建的叢集)，或[使用命名空間建立工作群組](https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-console-workgroups-create-workgroup-wizard.html) (適用於 Redshift Serverless)。

### 在資料倉儲上啟用區分大小寫
<a name="zero-etl-setting-up.case-sensitivity"></a>

若要成功整合，必須為資料倉儲啟用區分大小寫參數 ([https://docs.aws.amazon.com/redshift/latest/dg/r_enable_case_sensitive_identifier.html](https://docs.aws.amazon.com/redshift/latest/dg/r_enable_case_sensitive_identifier.html))。依預設，所有佈建的叢集和 Redshift Serverless 工作群組上都會停用區分大小寫。

若要啟用區分大小寫，請根據您的資料倉儲類型執行下列步驟：
+ **佈建的叢集** – 若要在佈建的叢集上啟用區分大小寫，請建立已啟用 `enable_case_sensitive_identifier` 參數的自訂參數群組。接著，將該參數群組與叢集建立關聯。如需指示，請參閱[使用主控台管理參數群組](https://docs.aws.amazon.com/redshift/latest/mgmt/managing-parameter-groups-console.html)或[使用 AWS CLI設定參數值](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-parameter-groups.html#configure-parameters-using-the-clil)。
**注意**  
在將自訂參數群組與叢集建立關聯之後，請記得重新啟動該叢集。
+ **無伺服器工作群組** - 若要在 Redshift Serverless 工作群組上啟用區分大小寫，您必須使用 AWS CLI。Amazon Redshift 主控台目前不支援修改 Redshift Serverless 參數值。傳送下列 [update-workgroup](https://docs.aws.amazon.com/cli/latest/reference/redshift-serverless/update-workgroup.html) 要求：

  ```
  aws redshift-serverless update-workgroup \
    --workgroup-name target-workgroup \
    --config-parameters parameterKey=enable_case_sensitive_identifier,parameterValue=true
  ```

  在修改工作群組的參數值之後，您不需要重新啟動該工作群組。

### 設定資料倉儲的授權
<a name="zero-etl.setup-auth"></a>

在建立資料倉儲之後，您必須將來源 RDS 資料庫設定為授權的整合來源。如需指示，請參閱[設定 Amazon Redshift 資料倉儲的授權](https://docs.aws.amazon.com/redshift/latest/mgmt/zero-etl-using.setting-up.html#zero-etl-using.redshift-iam)。

## 使用 AWS SDKs 設定整合
<a name="zero-etl.setup-sdk"></a>

您可以執行下列 Python 指令碼來為您自動設定所需的資源，而不用手動設定每個資源。程式碼範例使用 [適用於 Python (Boto3) 的 AWS SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html) 建立來源 RDS for MySQL 資料庫執行個體和目標資料倉儲，每個都具有必要的參數值。然後，在資料庫之間建立零 ETL 整合之前，它會等待資料庫可用。您可以根據您需要設定的資源來註解不同的函數。

若要安裝所需的相依性，請執行下列命令：

```
pip install boto3
pip install time
```

在指令碼中，選擇性地修改來源、目標和參數群組的名稱。最終函數會在設定資源後建立名為 `my-integration` 的整合。

### Python 程式碼範例
<a name="zero-etl.setup-sdk-python"></a>

```
import boto3
import time

# Build the client using the default credential configuration.
# You can use the CLI and run 'aws configure' to set access key, secret
# key, and default Region.

rds = boto3.client('rds')
redshift = boto3.client('redshift')
sts = boto3.client('sts')

source_db_name = 'my-source-db' # A name for the source database
source_param_group_name = 'my-source-param-group' # A name for the source parameter group
target_cluster_name = 'my-target-cluster' # A name for the target cluster
target_param_group_name = 'my-target-param-group' # A name for the target parameter group

def create_source_db(*args):
    """Creates a source RDS for MySQL DB instance"""

    response = rds.create_db_parameter_group(
        DBParameterGroupName=source_param_group_name,
        DBParameterGroupFamily='mysql8.0',
        Description='RDS for MySQL zero-ETL integrations'
    )
    print('Created source parameter group: ' + response['DBParameterGroup']['DBParameterGroupName'])

    response = rds.modify_db_parameter_group(
        DBParameterGroupName=source_param_group_name,
        Parameters=[
            {
                'ParameterName': 'binlog_format',
                'ParameterValue': 'ROW',
                'ApplyMethod': 'pending-reboot'
            },
            {
                'ParameterName': 'binlog_row_image',
                'ParameterValue': 'full',
                'ApplyMethod': 'pending-reboot'
            }
        ]
    )
    print('Modified source parameter group: ' + response['DBParameterGroupName'])

    response = rds.create_db_instance(
        DBInstanceIdentifier=source_db_name,
        DBParameterGroupName=source_param_group_name,
        Engine='mysql',
        EngineVersion='8.0.32',
        DBName='mydb',
        DBInstanceClass='db.m5.large',
        AllocatedStorage=15,
        MasterUsername='username',
        MasterUserPassword='Password01**'
    )
    print('Creating source database: ' + response['DBInstance']['DBInstanceIdentifier'])
    source_arn = (response['DBInstance']['DBInstanceArn'])
    create_target_cluster(target_cluster_name, source_arn, target_param_group_name)
    return(response)

def create_target_cluster(target_cluster_name, source_arn, target_param_group_name):
    """Creates a target Redshift cluster"""

    response = redshift.create_cluster_parameter_group(
        ParameterGroupName=target_param_group_name,
        ParameterGroupFamily='redshift-1.0',
        Description='RDS for MySQL zero-ETL integrations'
    )
    print('Created target parameter group: ' + response['ClusterParameterGroup']['ParameterGroupName'])

    response = redshift.modify_cluster_parameter_group(
        ParameterGroupName=target_param_group_name,
        Parameters=[
            {
                'ParameterName': 'enable_case_sensitive_identifier',
                'ParameterValue': 'true'
            }
        ]
    )
    print('Modified target parameter group: ' + response['ParameterGroupName'])

    response = redshift.create_cluster(
        ClusterIdentifier=target_cluster_name,
        NodeType='ra3.4xlarge',
        NumberOfNodes=2,
        Encrypted=True,
        MasterUsername='username',
        MasterUserPassword='Password01**',
        ClusterParameterGroupName=target_param_group_name
    )
    print('Creating target cluster: ' + response['Cluster']['ClusterIdentifier'])
    
    # Retrieve the target cluster ARN
    response = redshift.describe_clusters(
        ClusterIdentifier=target_cluster_name
    )
    target_arn = response['Clusters'][0]['ClusterNamespaceArn']

    # Retrieve the current user's account ID
    response = sts.get_caller_identity()
    account_id = response['Account']

    # Create a resource policy granting access to source database and account ID
    response = redshift.put_resource_policy(
        ResourceArn=target_arn,
        Policy='''
        {
            \"Version\":\"2012-10-17\",		 	 	 
            \"Statement\":[
                {\"Effect\":\"Allow\",
                \"Principal\":{
                    \"Service\":\"redshift.amazonaws.com\"
                },
                \"Action\":[\"redshift:AuthorizeInboundIntegration\"],
                \"Condition\":{
                    \"StringEquals\":{
                        \"aws:SourceArn\":\"%s\"}
                    }
                },
                {\"Effect\":\"Allow\",
                \"Principal\":{
                    \"AWS\":\"arn:aws:iam::%s:root\"},
                \"Action\":\"redshift:CreateInboundIntegration\"}
            ]
        }
        ''' % (source_arn, account_id)
    )
    return(response)

def wait_for_db_availability(*args):
    """Waits for both databases to be available"""

    print('Waiting for source and target to be available...')

    response = rds.describe_db_instances(
        DBInstanceIdentifier=source_db_name
    )
    source_status = response['DBInstances'][0]['DBInstanceStatus']
    source_arn = response['DBInstances'][0]['DBInstanceArn']

    response = redshift.describe_clusters(
        ClusterIdentifier=target_cluster_name
    )
    target_status = response['Clusters'][0]['ClusterStatus']
    target_arn = response['Clusters'][0]['ClusterNamespaceArn']

    # Every 60 seconds, check whether the databases are available
    if source_status != 'available' or target_status != 'available':
        time.sleep(60)
        response = wait_for_db_availability(
            source_db_name, target_cluster_name)
    else:
        print('Databases available. Ready to create zero-ETL integration.')
        create_integration(source_arn, target_arn)
        return

def create_integration(source_arn, target_arn):
    """Creates a zero-ETL integration using the source and target databases"""

    response = rds.create_integration(
        SourceArn=source_arn,
        TargetArn=target_arn,
        IntegrationName='my-integration'
    )
    print('Creating integration: ' + response['IntegrationName'])
    
def main():
    """main function"""
    create_source_db(source_db_name, source_param_group_name)
    wait_for_db_availability(source_db_name, target_cluster_name)

if __name__ == "__main__":
    main()
```

## 步驟 3b：建立 Amazon SageMaker Lakehouse 零 ETL 整合的 AWS Glue 目錄
<a name="zero-etl-setting-up.sagemaker"></a>

與 Amazon SageMaker Lakehouse 建立零 ETL 整合時，您必須在其中建立 AWS Glue 受管目錄 AWS Lake Formation。目標目錄必須是 Amazon Redshift 受管目錄。若要建立 Amazon Redshift 受管目錄，請先建立 `AWSServiceRoleForRedshift` 服務連結角色。在 Lake Formation 主控台中，將 `AWSServiceRoleForRedshift` 新增為唯讀管理員。

如需有關先前任務的詳細資訊，請參閱下列主題。
+ 如需有關建立 Amazon Redshift 受管目錄的詳細資訊，請參閱《AWS Lake Formation 開發人員指南》**中的[在 AWS Glue Data Catalog中建立 Amazon Redshift 受管目錄](https://docs.aws.amazon.com/lake-formation/latest/dg/create-rms-catalog.html)。
+ 如需 Amazon Redshift 服務連結角色的詳細資訊，請參閱《Amazon Redshift 管理指南》**中的[使用 Amazon Redshift 的服務連結角色](https://docs.aws.amazon.com/redshift/latest/mgmt/using-service-linked-roles.html)。
+ 如需 Lake Formation 唯讀管理員許可的詳細資訊，請參閱《AWS Lake Formation 開發人員指南》**中的 [Lake Formation 角色和 IAM 許可參考](https://docs.aws.amazon.com/lake-formation/latest/dg/permissions-reference.html)。

### 設定目標 AWS Glue 目錄的許可
<a name="zero-etl-setting-up.sagemaker-permissions"></a>

在建立零 ETL 整合的目標目錄之前，您必須建立 Lake Formation 目標建立角色和 AWS Glue 資料傳輸角色。使用 Lake Formation 目標建立角色來建立目標目錄。建立目標目錄時，請在**從引擎存取區段**的 **IAM 角色**欄位中輸入 Glue 資料傳輸角色。

#### Lake Formation 目標建立角色
<a name="zero-etl-setting-up.target-creation-role"></a>

目標建立角色必須是 Lake Formation 管理員，且需要下列許可。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "lakeformation:RegisterResource",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutEncryptionConfiguration",
                "iam:PassRole",
                "glue:CreateCatalog",
                "glue:GetCatalog",
                "s3:PutBucketTagging",
                "s3:PutLifecycleConfiguration",
                "s3:PutBucketPolicy",
                "s3:CreateBucket",
                "redshift-serverless:CreateNamespace",
                "s3:DeleteBucket",
                "s3:PutBucketVersioning",
                "redshift-serverless:CreateWorkgroup"
            ],
            "Resource": [
                "arn:aws:glue:*:111122223333:catalog",
                "arn:aws:glue:*:111122223333:catalog/*",
                "arn:aws:s3:::*",
                "arn:aws:redshift-serverless:*:111122223333:workgroup/*",
                "arn:aws:redshift-serverless:*:111122223333:namespace/*",
                "arn:aws:iam::111122223333:role/GlueDataCatalogDataTransferRole"
            ]
        }
    ]
}
```

------

目標建立角色必須具有下列信任關係。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "glue.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        },
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::111122223333:user/Username"
          },
          "Action": "sts:AssumeRole"
        }
    ]
}
```

------

#### Glue 資料傳輸角色
<a name="zero-etl-setting-up.glue-data-transfer-role"></a>

MySQL 目錄操作需要 Glue 資料傳輸角色，且必須具有下列許可。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "DataTransferRolePolicy",
            "Effect": "Allow",
            "Action": [
                "kms:GenerateDataKey",
                "kms:Decrypt",
                "glue:GetCatalog",
                "glue:GetDatabase"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

------

Glue 資料傳輸角色必須具有下列信任關係。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "glue.amazonaws.com",
                    "redshift.amazonaws.com"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

------

## 後續步驟
<a name="zero-etl.setup-next"></a>

透過來源 RDS 資料庫和 Amazon Redshift 目標資料倉儲或 Amazon SageMaker Lakehouse，您可以建立零 ETL 整合並複寫資料。如需說明，請參閱[建立與 Amazon Redshift 的 Amazon RDS 零 ETL 整合](zero-etl.creating.md)。