Redshift Serverless
Redshift Serverlessは今年のre:Inventで発表された、インスタンスを立てることなく従量課金でペタバイトスケールのDWHであるRedshiftを使える機能。 S3のデータを直接参照できるRedshift SpectrumやRDSへのFederated Query、機械学習のRedshift MLも使える。 分析のような不定期に発生する需要のためにインスタンスを立てておくのはコストの上でハードルが高かったのでこのアップデートは嬉しい。
料金は最低1分のオートスケールするRPU (2vCPU, 16GiBメモリ)時間とストレージに対してかかり、オレゴンリージョンなどが $0.45/RPU hour なのに対して東京はなぜか $0.70/RPU hour と少し割高な設定になっている。2vCPU, 15 GiBメモリのインスタンスdc2.largeがオンデマンドで $0.314/hour なので、利用頻度が少なかったり不定期なために平均40%以上リソースが使えていない場合のコストは抑えられそうだ。RIが最大まで効いている場合は $0.110/hour となり15%まで閾値が下がるが、スケールを気にしなくて良いのは運用の上ではメリットがある。また、Redshift Spectrumのロード量に対する課金は発生しない。
(追記: 2022-07-13) GAになったタイミングでオレゴンは $0.36/RPU hour 東京は $0.494/RPU hour まで料金が下がった。
他のサーバーレス集計サービス
サーバーレスで集計を行える他のサービスとしてはPrestoのマネージドサービスであるAthenaやSparkのマネージドサービスであるGlueがあって、前者は手軽にクエリを実行できロード量による課金も分かりやすいが、実行時間や同時実行数などの制約があり、後者は時間のかかる集計も行うことができるがジョブを作る必要があってアドホックな実行にはあまり向かない。
これらはHive Metastoreに対応しており、その互換サービスであるGlue Data Catalogでスキーマを共有できるので用途に応じて使い分けることもできるが、使える文法に差があったり、同じクエリを実行しても異なる結果を返すことがあったりと、移植する際には注意する必要がある。
Athena(Presto)とGlue(Spark)で同じクエリを実行した際に異なる値が返る原因 - sambaiz-net
また、いずれもRDSに加えてDynamoDBやMongoDBなどのコネクタが用意されており、カスタムコネクタを用いることで他のデータソースにも接続することができる。
AthenaのFederated QueryでTPC-DS Connectorを用いてデータを生成する - sambaiz-net
GlueのカスタムコネクタでBigQueryに接続する - sambaiz-net
同じく今年のre:Inventで発表されたEMR Serverlessもある。 巨大なデータに対して重い集計や repartition() を行ったりするとOOMや No space left on device になることがあるが、Glueだとスケールアップできないため物理的に解決が難しいことがあり、そういった場合はEMRを検討すると良いかもしれない。
AWS CLIでEMRクラスタを立ち上げSparkのアプリケーションを実行する - sambaiz-net
サードパーティにも目を向ければ各クラウドにホストされるSnowflakeがある。コストやスケールの容易さのためにRedshiftからSnowflakeに移行した事例もあり良い評判を目にするが、立ち位置が近いRedshift Serverlessが発表されたことでこれからの技術選定に影響があるかもしれない。料金はプランによって単価が異なるSnowflake Creditとストレージに対してかかる。
他にはAnthosを用いてマルチクラウドでクエリエンジンを動かすBigQuery Omniもある。今年の10月にGAになったばかりで、対応リージョンがまだ少なく、料金も従量課金でないので他と同様に使うイメージではないが、データを転送することなくAWS上でBigQueryのクエリを実行できるのは待望の機能なので今後の動きが気になる。
Glue Data Catalogのテーブルにクエリを実行する
CDKでData CatalogのDatabaseとTable、それらにアクセスできるRoleを作成する。
CDKでGlue Data CatalogのDatabase,Table,Partition,Crawlerを作成する - sambaiz-net
これも今年のre:Inventで発表があったが、ついにCDKのv2がstableになったのでv2で書く。 各サービスのパッケージ @aws-cdk/aws-xxx がaws-cdk-libに統合され、alphaのものだけ旧パッケージ名に-alphaを付けたものになった。
$ npx [email protected] init app --language typescript
$ npm install --save aws-cdk-lib
$ npm install --save @aws-cdk/aws-glue-alpha
Redshift Serverlessで用いるRoleはPrincipalに redshift.amazonaws.comとredshift-serverless.amazonaws.comを入れる必要がある。
const db = new Database(this, 'Database', {
databaseName: "test_db",
})
const bucket = new Bucket(this, 'Bucket', {
bucketName: `redshift-serverless-test-${this.account}-${this.region}`
})
new BucketDeployment(this, 'DeployWebsite', {
sources: [Source.asset('./data')],
destinationBucket: bucket,
destinationKeyPrefix: 'test_table/',
});
const table = new Table(this, 'TestTable', {
tableName: "test_table",
database: db,
columns: [{
name: "id",
type: Schema.BIG_INT,
}],
dataFormat: DataFormat.JSON,
bucket: bucket,
s3Prefix: "test_table/",
compressed: false,
})
const role = new Role(this, 'SchemaRole', {
assumedBy: new CompositePrincipal(
new ServicePrincipal('redshift.amazonaws.com'),
new ServicePrincipal('redshift-serverless.amazonaws.com')
)
})
role.addToPolicy(new PolicyStatement({
resources: [
db.databaseArn,
db.catalogArn,
table.tableArn
],
actions: ['glue:Get*'],
}))
role.addToPolicy(new PolicyStatement({
resources: [
bucket.bucketArn,
`${bucket.bucketArn}/*`,
],
actions: ['s3:Get*', 's3:List*'],
}))
})
作ったRoleをエンドポイントに関連付けてSchema作成時に選べるようにする。
リソース一覧のServerlessをクリックして接続した後、Data CatalogのDatabaseとRoleを指定してRedshiftのExternal Schemaを作成する。
これでData CatalogのTableに対してクエリを実行できる。 リソース一覧にTableが表示されない場合はRoleにTableを取得する権限がついているかを確認する。
Data Catalogを参照するAthenaからも同様のクエリが実行できる。こちらはSchemaを作成したりする必要がない。
Redshift ServerlessとAthenaの性能をTPC-DSのクエリで比較する - sambaiz-net
参考
Redshift から Snowflake に移行しました | CyberAgent Developers Blog
Amazon Redshift の 進化の歴史とこれから/redshift-evolution-2021 - Speaker Deck