Single AZなVPCに作成したRedshiftクラスターのクラスター再配置をあとから有効にすることはできますか?
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。
結論として前提としてVPCに別AZなSubnetを作る必要はありますが、答えとしては、できますが答えとなります。 その際にRedshiftクラスタの作り直しは必要なく、Redshiftクラスタの再起動が行われます。
以下では実際にSingle AZなVPCを構築し、別AZのSubnetをVPCに追加とその後クラスタの再配置を有効にしてみました。
クラスター再配置って何?
Redshiftの可用性を上げる機能の一つです。 クラスタの再配置については以下が特徴となります。
- データの損失やアプリケーションへの変更なしに、クラスターを別のアベイラビリティーゾーン (AZ) に移動させることができます。
- 追加料金はかかりません
- Amazon Redshift クラスターが新しいアベイラビリティーゾーンに再配置されると、新しいクラスターは元のクラスターと同じエンドポイントを持ちます。
- Amazon Redshift クラスターの再配置は、ra3.16xlarge、ra3.4xlarge、ra3.xlplus などの RA3 インスタンスタイプでのみサポートされています。
Amazon Redshift でのクラスター再配置の管理 - Amazon Redshift
このような特徴がある機能のため、上記のドキュメントをを参考に制約条件に引っかからないのであれば有効にしておくべき機能と言えます。
実際にSingle AZなRedshiftをMulti-AZなSubnetに配置して、クラスター再配置を有効にしてみた。
手順としては、以下の手順で行いました。
- Single AZなVPCでRedshiftを構築する
- VPCに異なるAvailabilityZoneのSubnetを追加し、RedshiftのSubnetGroupに追加する
- Redshiftのクラスタ再配置を有効にする
Single AZで構築したRedshiftを作ってみる。
以下のようなCloudformationのテンプレートを用いて、まずはSingle AZなVPC上にRedshiftを構築します。 (行数が多いので、全体はトグルを開いて確認してください)
Signel AZなVPCとRedsfhitクラスタを構築するCloudformationテンプレート
AWSTemplateFormatVersion: 2010-09-09 Description: Redshift Env Parameters: Prefix: Description: Prefix Type: String Default: cm-kajiwara-sample MasterUsername: Type: "String" Default: "admin" CidrBlock: Description: Please type the CidrBlock. Type: String Default: 192.168.0.0/22 MasterUserPasswordSSMParam: Type: String Description: colons-separated parameter name and version for master user's password for DB instance. e.x. parameter-name:1 Resources: #----------------------------------------------------------------------------- # VPC #----------------------------------------------------------------------------- VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Sub ${CidrBlock} EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub "${Prefix}-vpc" PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub "${Prefix}-private-rtb" PrivateSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !GetAZs ] VpcId: !Ref VPC CidrBlock: !Select [ 0, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]] Tags: - Key: Name Value: !Sub "${Prefix}-private-subnet" InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Application Value: Ref: AWS::StackId - Key: Network Value: Public AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: Ref: VPC InternetGatewayId: Ref: InternetGateway #----------------------------------------------------------------------------- # Securty Group #----------------------------------------------------------------------------- RedshiftSecurityGroup: Type: "AWS::EC2::SecurityGroup" Properties: GroupDescription: !Sub "${Prefix}-redshift-sg" GroupName: !Sub "${Prefix}-redshift-sg" Tags: - Key: "Name" Value: !Sub "${Prefix}-redshift-sg" VpcId: !Ref VPC SecurityGroupEgress: - CidrIp: "0.0.0.0/0" IpProtocol: "-1" #----------------------------------------------------------------------------- # IAM #----------------------------------------------------------------------------- RedshiftRole: Type: "AWS::IAM::Role" Properties: Path: "/" RoleName: !Sub "${Prefix}-redshift-role" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - redshift.amazonaws.com Action: sts:AssumeRole MaxSessionDuration: 3600 ManagedPolicyArns: - "arn:aws:iam::aws:policy/AmazonS3FullAccess" Description: "Allows Redshift clusters to call AWS services on your behalf." Tags: - Key: "Name" Value: !Sub "${Prefix}-redshift-role" #----------------------------------------------------------------------------- # Redshift #----------------------------------------------------------------------------- RedshiftClusterSubnetGroup: Type: "AWS::Redshift::ClusterSubnetGroup" Properties: Description: !Sub "${Prefix}-redshift-subnet-group" SubnetIds: - !Ref PrivateSubnet1 RedshiftClusterParameterGroup: Type: "AWS::Redshift::ClusterParameterGroup" Properties: Description: !Sub "${Prefix}-redshift-parameter-group" ParameterGroupFamily: "redshift-1.0" Parameters: - ParameterName: "require_ssl" ParameterValue: "true" RedshiftCluster: Type: "AWS::Redshift::Cluster" Properties: ClusterIdentifier: !Sub "${Prefix}-redshift" ClusterType: multi-node NumberOfNodes: 2 NodeType: ra3.xlplus MasterUsername: !Ref MasterUsername MasterUserPassword: !Sub "{{resolve:ssm-secure:${MasterUserPasswordSSMParam}}}" DBName: !Sub "${Prefix}-db" AutomatedSnapshotRetentionPeriod: 35 VpcSecurityGroupIds: - !Ref RedshiftSecurityGroup EnhancedVpcRouting: true ClusterParameterGroupName: !Ref RedshiftClusterParameterGroup ClusterSubnetGroupName: !Ref RedshiftClusterSubnetGroup AvailabilityZone: !Select [ 0, !GetAZs ] PreferredMaintenanceWindow: sat:18:00-sat:18:30 ClusterVersion: "1.0" AllowVersionUpgrade: true PubliclyAccessible: false IamRoles: - !GetAtt RedshiftRole.Arn
上記のテンプレートを以下のようなシェルで構築します。
set -eu export AWS_PAGER="" MasterUserPasswordSSMParam="/cm-kajiwara/redshift/master-password:3" aws cloudformation deploy --stack-name cm-kajiwara-redshift-sample --template-file vpc_redshift-solo.yaml --no-execute-changeset \ --capabilities CAPABILITY_NAMED_IAM \ --parameter-overrides \ MasterUserPasswordSSMParam=$MasterUserPasswordSSMParam
当然Single AZなVPCに構築しているため、クラスタ再配置は有効になっておりません。
VPCに異なるAvailabilityZoneのSubnetを追加し、RedshiftのSubnetGroupに追加する
上記のYamlに以下のように記載して、Subnetを追加と追加したSubnetをRedshiftのSubnet Groupに追加します。
PrivateSubnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !GetAZs ] VpcId: !Ref VPC CidrBlock: !Select [ 0, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]] Tags: - Key: Name Value: !Sub "${Prefix}-private-subnet" PrivateSubnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 1, !GetAZs ] VpcId: !Ref VPC CidrBlock: !Select [ 1, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]] Tags: - Key: Name Value: !Sub "${Prefix}-private-subnet"
RedshiftClusterSubnetGroup: Type: "AWS::Redshift::ClusterSubnetGroup" Properties: Description: !Sub "${Prefix}-redshift-subnet-group" SubnetIds: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2
これを実行するだけではクラスタの再配置は有効にならず、またRedshiftの再起動も実施されません。
Redshiftのクラスタ再配置を有効にする
以下のように追記すると、Redshiftのクラスタ再配置が有効になります。
RedshiftCluster: Type: "AWS::Redshift::Cluster" Properties: ClusterIdentifier: !Sub "${Prefix}-redshift" ClusterType: multi-node NumberOfNodes: 2 NodeType: ra3.xlplus MasterUsername: !Ref MasterUsername MasterUserPassword: !Sub "{{resolve:ssm-secure:${MasterUserPasswordSSMParam}}}" DBName: !Sub "${Prefix}-db" AutomatedSnapshotRetentionPeriod: 35 VpcSecurityGroupIds: - !Ref RedshiftSecurityGroup EnhancedVpcRouting: true ClusterParameterGroupName: !Ref RedshiftClusterParameterGroup ClusterSubnetGroupName: !Ref RedshiftClusterSubnetGroup AvailabilityZone: !Select [ 0, !GetAZs ] AvailabilityZoneRelocation: true PreferredMaintenanceWindow: sat:18:00-sat:18:30 ClusterVersion: "1.0" AllowVersionUpgrade: true PubliclyAccessible: false IamRoles: - !GetAtt RedshiftRole.Arn
このタイミングでRedshiftのクラスタの再起動が実施されることとなり、Redshiftのクラスタ再配置が有効になります。
まとめ
Signal AZな構成で組んだVPC RedshiftであってもVPCに別AZのSubnetが追加可能であれば、あとからクラスタの再配置を有効にすることはできます。 その際にRedshiftクラスタの再起動は必要となりますが、この機能を有効にするにあたって追加の費用はかからずRedshiftの可用性を上げる方法の一つとなりますので、 有効になっていない場合は有効を検討していただければと思います。