#概要
S3バケット内に保存したオブジェクトに対して簡単なSQL文でクエリができるサービス、S3 Selectを利用する機会がありまして、その内容を軽く共有しようと思います。今回に初めて利用してみましたが、とても簡単で便利だったので、色んなところで利用できると感激しました。
#背景
ウェブページユーザーが操作した内容をロギングする必要がありました。そして、操作ログを閲覧、様々な検索が可能なページも用意する必要がありました。
このような仕様で、まず、検索するログを入れて置くAWSサービスを選ぶことになりました。DynamoDB, RDS、Kinesis Firehose&Elasticsearch、CloudWatch Logs Insights、などなどの方法で悩んでましたが、結局は仕様と費用などのため、ログを貯めておくストレージをS3にして、Athenaより安いS3 Selectを利用することになりました。
※ スキャンデータ1GB当たり(東京) S3 Selectは0.005USD、Athenaは0.00225USD
#注意
- Athenaと違って複数のオブジェクトでクエリはできません。
- 対象オブジェクトはCSV形式とJSON形式だけ可能です。
- SQLはSELECT,FROM,WHERE,LIMITしかできません。
- サブクエリや結合はサポートされていません。
- SQL式の最大長は256KBです。
- 結果のレコードの最大長は1MBです。
- など
#利用
PHP版のAWS SDKでささっと利用してみます。
※ https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#selectobjectcontent
※ https://github.com/aws/aws-sdk-php/pull/1627
サンプルjsonデータを用意してテスト用のS3バケットに入れる
{id:1,name:"lee",stauts:3,created:"2018-02-2819:38:54"}
{id:2,name:"hoge",stauts:3,created:"2018-03-2819:38:54"}
{id:3,name:"lee",stauts:1,created:"2018-04-2819:38:54"}
{id:4,name:"hoge",stauts:2,created:"2018-05-2819:38:54"}
{id:5,name:"lee",stauts:1,created:"2019-06-2819:38:54"}
{id:6,name:"hera",stauts:3,created:"2018-07-2819:38:54"}
$s3 = \App::make('aws')->createClient('s3');
$result = $s3->selectObjectContent([
'Bucket' => 'lee-dev',
'Key' => 's3-select/test.json',
'ExpressionType' => 'SQL',
'Expression' => "SELECT * FROM S3Object S WHERE S.name = 'lee'",
'InputSerialization' => [
'JSON' => [
'Type' => 'Lines',
],
],
'OutputSerialization' => [
'JSON' => [
'RecordDelimiter' => '\n',
],
],
]);
foreach ($result['Payload'] as $event) {
if (isset($event['Records'])) {
echo (string) $event['Records']['Payload'] . PHP_EOL;
}
}
{"id":1,"name":"lee","stauts":3,"created":"2018-02-2819:38:54"}
{"id":3,"name":"lee","stauts":1,"created":"2018-04-2819:38:54"}
{"id":5,"name":"lee","stauts":1,"created":"2019-06-2819:38:54"}