この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。
結論として前提として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テンプレート
vpc_redshift-solo.yaml
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の可用性を上げる方法の一つとなりますので、 有効になっていない場合は有効を検討していただければと思います。