クラウドインフラ構築記

現在AWSの構築支援に携わっております。今注視しているのは、GKE、BigQuery、Google Dataflowなどサービスを展開しているGoolge Cloud Platformです。

2018年7月8日
から hiruta
kubernatesでRegional Persistent Disksを使うには #gcpug はコメントを受け付けていません。

kubernatesでRegional Persistent Disksを使うには #gcpug

Regional Persistent Disksについて

Persistent Disksは1ゾーンのみで使用できるものだが、Regional Persistent Disks は異なるゾーンにインスタンスにアタッチができる。
ディスクの内容はレプリケーションしてくれる。

regional persistent disks provide durable storage and replication of data between two zones in the same region.

Persistent Disksの作成

 gcloud beta compute disks create web-disk-2 --size 30GB --type pd-ssd --region asia-east1 --replica-zones asia-east1-a,asia-east1-b 

–replica-zonesに、2ゾーンを指定する。ただし、3 ゾーンを指定すると、–replica-zones: too many args となり、作成できない。

最初に作成されたディスクの確認をします。

 $ gcloud beta compute disks list
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS
web-disk-2 asia-east1 region 30 pd-ssd READY  

7/8現在、Web コンソールからはRegional Persistent Disksを確認できない。

regional diskのwriteモードでのアタッチは1インスタンスしかできないことは、Persistent Disksと同じ
Persistent Disksだと、ROMだと別のインスタンスにアタッチが可能

Regional Persistent Disksについては下記を参照してください。
https://cloud.google.com/compute/docs/disks/regional-persistent-disk

kubernatesでRegional Persistent Disksを使うには

regional diskをPersistentVolumeで使う場合、下記のように、PersistentVolumeを作成します
( failure-domain.beta.kubernetes.io/zoneタグが要)
※https://kubernetes.io/docs/concepts/storage/volumes/

 apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
failure-domain.beta.kubernetes.io/zone: asia-east1-a__asia-east1-b
spec:
storageClassName: manual
capacity:
storage: 30Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: web-disk-2
fsType: ext4 

kubernetesのmaster versionは、1.10が必要(1.10.5-gke.0で動確)
それ以下だとPersistentVolumeでエラーとなります。

 $ kubectl create -f test.yml
Error from server (Forbidden): error when creating "test.yml": persistentvolumes "task-pv-volume" is forbidden: error querying GCE PD volume web-disk-2: The regional PD feature is only available via the GCE Alpha API. Enable "GCEDiskAlphaAPI" in the list of "alpha-features" in "gce.conf" to use the feature. 

次に、PersistentVolumeClaimの作成

 kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
 $ kubectl create -f task-pv-claim.yml
persistentvolumeclaim "task-pv-claim" created
$ kubectl get pvc task-pv-claim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 30Gi RWO manual 9s
$ kubectl get pv task-pv-volume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 30Gi RWO Retain Bound default/task-pv-claim manual 

task-pv-claimをPodからマウントするコンフィグを作成

 apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: web-app
labels:
app: WebApp
spec:
template:
metadata:
labels:
app: mysql-client
spec:
containers:
- name: web
image: asia.gcr.io/xxxxxxxxxxxxxxx/nginx:latest
ports:
- containerPort: 8080
env:
- name: WORDPRESS_DB_HOST
value: 127.0.0.1:3306
# These secrets are required to start the pod.
# [START cloudsql_secrets]
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
# [END cloudsql_secrets]
volumeMounts:
- name: task-pv-storage
mountPath: /www
- name: php-fpm
image: asia.gcr.io/xxxxxxxxxxxxxxx/php-fpm:latest
ports:
- containerPort: 9000
# Change <INSTANCE_CONNECTION_NAME> here to include your GCP
# project, the region of your Cloud SQL instance and the name
# of your Cloud SQL instance. The format is
# $PROJECT:$REGION:$INSTANCE
# [START proxy_container]
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=xxxxxxxxxxxxxxx:asia-east1:web2-db=tcp:3306",
"-credential_file=/secrets/cloudsql/credentials.json"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
# [END proxy_container]
# [START volumes]
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
# [END volumes] 
 kubectl apply -f deployment.yml 

でデプロイし、Podにログインして、Regional Persistent Disksが、マウントされていることを確認しました。

 root@web-app-84dcf8d8c8-vdnjp:/# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
|-sda1 8:1 95.9G 0 part /etc/hosts
|-sda2 8:2 0 16M 0 part
|-sda3 8:3 0 2G 0 part
|-sda4 8:4 0 16M 0 part
|-sda5 8:5 0 2G 0 part
|-sda6 8:6 512B 0 part
|-sda7 8:7 0 512B 0 part
|-sda8 8:8 16M 0 part
|-sda9 8:9 0 512B 0 part
|-sda10 8:10 0 512B 0 part
|-sda11 8:11 8M 0 part
`-sda12 8:12 0 32M 0 part
sdb 8:16 0 30G 0 disk /www 

 

2018年6月24日
から hiruta
nginx + php-fpm + cloudsql proxyのPodを作成手順メモ #gcpja はコメントを受け付けていません。

nginx + php-fpm + cloudsql proxyのPodを作成手順メモ #gcpja

nginx + php-fpm + cloudsql proxy のコンテナで構成されたPod、External Load BalancerのServiceを構築したときのメモになります。

Kubernets Enginesを作成します。Preemptible VM Nodeで作成しています。

 gcloud container clusters create test-cluster --machine-type=g1-small --network=product-network --subnetwork=prod-asia --preemptible 

CloudSQLへの接続ユーザ情報からsecretを作成しておきます。

 kubectl create secret generic cloudsql-db-credentials --from-literal=username=proxyuser --from-literal=password=xxxxx 

CloudSQL Admin、CloudSQL Client、CloudSQL Editorの権限を持つIAMを作成、credentials.jsonを取得します

 kubectl create secret generic cloudsql-instance-credentials --from-file=credentials.json=credentials.json 

各構成しているnginx、php-fpmは下記を参考に作成しました。

GCRにイメージをpushする前にGCRと認証済みにしておき必要があります。以下コマンドを実行しておきます。

 gcloud auth configure-docker 

docker pushするには、下記も必要になります。

 docker login -u oauth2accesstoken -p "$(gcloud auth print-access-token)" https://asia.gcr.io 

 

Pod構成ファイルの作成

 apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql-client
labels:
app: mysql-client
spec:
template:
metadata:
labels:
app: mysql-client
spec:
containers:
- name: web
image: asia.gcr.io/[project-id]/nginx:latest
ports:
- containerPort: 8080
env:
- name: WORDPRESS_DB_HOST
value: 127.0.0.1:3306
# These secrets are required to start the pod.
# [START cloudsql_secrets]
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-db-credentials
key: password
# [END cloudsql_secrets]
- name: php-fpm
image: asia.gcr.io/[project-id]/php-fpm:latest
ports:
- containerPort: 9000
# Change <INSTANCE_CONNECTION_NAME> here to include your GCP
# project, the region of your Cloud SQL instance and the name
# of your Cloud SQL instance. The format is
# $PROJECT:$REGION:$INSTANCE
# [START proxy_container]
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/cloud_sql_proxy",
"-instances=[project-id]:asia-east1:web2-db=tcp:3306",
"-credential_file=/secrets/cloudsql/credentials.json"]
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
# [END proxy_container]
# [START volumes]
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
# [END volumes] 

Service用構成ファイルの作成

 apiVersion: v1
kind: Service
metadata:
name: web
spec:
ports:
-
port: 80
targetPort: 8080
selector:
app: mysql-client
type: LoadBalancer

Podから作成しておきます。

  kubectl create -f deployment.yaml 
  kubectl create -f service-web.yaml 

https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/ にも記載されている通り、SSL termination する場合は、Ingress resourceが必要になります。

2018年5月13日
から hiruta
[StandardSQL] 過去スナップショット参照方法について #gcpug はコメントを受け付けていません。

[StandardSQL] 過去スナップショット参照方法について #gcpug

Legacy SQLのTable Decorators に該当するものが、Standard SQLにないものか

issue https://issuetracker.google.com/issues/35905931のコメントをみて、発見したことですが、FOR SYSTEM TIME AS OFというものがあることが判明

https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#from-clause

制限

FROM句で、ARRAY scan、UNNEST operator、WITH句によって定義されたtable expressionも使えない。

過去7日のタイムスタンプである必要がある、もちろん、未来日付はNG

データリカバリの確認

 bq query --use_legacy_sql=false 'DELETE FROM dlp_output.earthquake_data WHERE true' 

と過去データレコードを全部削除ののち、

 bq query --destination_table xxxxxxxxxxxxxx:dlp_output.earthquake_data --append --use_legacy_sql=false 'SELECT * FROM dlp_output.earthquake_data FOR SYSTEM TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR);'

Amazon Auroraにも、過去レコードに戻す機能(Amazon Aurora Backtrack)が最近リリースされましたが、
クラスタの内容を過去(72Hours)に戻してしまうので、クエリで過去の情報を確認するものではない。

https://aws.amazon.com/blogs/aws/amazon-aurora-backtrack-turn-back-time/

2018年3月26日
から hiruta
Google-Provided Templates #gcpug はコメントを受け付けていません。

Google-Provided Templates #gcpug

Google Dataflow用のGoogleがテンプレートを提供してくれている。Dataflowをパラメータを指定することでDataflowを手軽に使うことができるものです。

現在提供されているテンプレートは以下となります。

  • WordCount
  • Cloud Pub/Sub to BigQuery
  • Cloud Storage Text to Cloud Pub/Sub
  • Cloud Pub/Sub to Cloud Storage Text
  • Cloud Datastore to Cloud Storage Text
  • Cloud Storage Text to BigQuery
  • Cloud Storage Text to Cloud Datastore
  • Bulk Decompress Cloud Storage Files

その中のCloud Storage Text to BigQuery について、

テンプレートで指定するパラメータは以下となっている。

実行方法として、Google Cloud Platform consoleもしくは、Google OAuth 2.0されたREST API で実行できます。

https://cloud.google.com/dataflow/docs/reference/rest/v1b3/projects.templates/launch#authorization

 

が、そのまま実行させると、inputパラメータを指定すると、invailidとなります。

outputTableの、my-project-nameは、project-idでないとprojectが見つからないと怒られます。

 {
"parameters": {
"javascriptTextTransformFunctionName": "transform",
"JSONPath": "gs://**********/schema.json",
"javascriptTextTransformGcsPath": "gs://**********/my_function.js",
"inputFilePattern": "gs://**********/*.csv",
"outputTable": "*************:testdataset.testtable",
"bigQueryLoadingTemporaryDirectory": "gs://**********/tmp"
},
"jobName": "test-job",
"environment": {
"tempLocation": "gs://**********/temp",
"zone": "us-central1-f"
}
}

テンプレートのソースを確認しても、InputFilePatternパラメータが必須となっているので、inputFilePatternの間違いであるのは確実です。

2018年2月25日
から hiruta
GCS Triggerイベントから返される値がおかしい #gcpug はコメントを受け付けていません。

GCS Triggerイベントから返される値がおかしい #gcpug

GCS Triggerイベントから返される値が、おかしい場合がある。

以下簡単なコードを用意し、

 exports.bqbilling =function(event,callback) {
const file = event.data;
console.log(' file ', file); }

以下でfunctionsをデプロイを行いました。

 gcloud beta functions deploy bqbilling --trigger-resource upload_bucket_us --trigger-event google.storage.object.finalize 

以下2パターンでGCSバケットにコピーしてみました。

 gsutil cp billing-2018-02-23.json gs://upload_bucket_us 
 gsutil cp billing-2018-02-23.json gs://upload_bucket_us/billing-2018-02-23.json 

後者が、下記file.nameに、billing-2018-02-23.json/billing-2018-02-23.jsonと重複して入ってしまう。

 file : { bucket: 'upload_bucket_us', contentLanguage: 'en', contentType: 'application/json', crc32c: 'oV5QaA==', etag: 'CICXiNWhwNkCEAE=', generation: '1519534106348416', id: 'upload_bucket_us/billing-2018-02-23.json/billing-2018-02-23.json/1519534106348416', kind: 'storage#object', md5Hash: 'YhMH7RRG8oPxYj1lTapNBw==', mediaLink: 'https://www.googleapis.com/download/storage/v1/b/upload_bucket_us/o/billing-2018-02-23.json%2Fbilling-2018-02-23.json?generation=1519534106348416&alt=media', metageneration: '1', name: 'billing-2018-02-23.json/billing-2018-02-23.json', selfLink: 'https://www.googleapis.com/storage/v1/b/upload_bucket_us/o/billing-2018-02-23.json%2Fbilling-2018-02-23.json', size: '67081', storageClass: 'NEARLINE', timeCreated: '2018-02-25T04:48:26.346Z', timeStorageClassUpdated: '2018-02-25T04:48:26.346Z', updated: '2018-02-25T04:48:26.346Z' } 

gcloudは、190.0.1(最新版)で試しました。

2018年2月24日
から hiruta
Cloud Functions Storage Triggers 仕様変更について #gcpug はコメントを受け付けていません。

Cloud Functions Storage Triggers 仕様変更について #gcpug

Cloud Functions Storage Triggersの仕様が、object.changeから変更になりました。

▪ **(MODIFIED)** The default trigger event behavior for
–trigger-bucket flag on the gcloud functions deploy command will soon
change. google.storage.object.finalize will replace
providers/cloud.storage/eventTypes/object.change as default trigger
event. To opt-in to the new behavior early, run gcloud config set
functions/use_new_object_trigger True.

Functions新仕様でのデプロイコマンドになります。trigger-resourceとtriiger-eventを指定するようになります。

 gcloud beta functions deploy bqbilling --trigger-resource prd-billing --trigger-event google.storage.object.finalize 

Cloud FunctionsとAWS Lambdaのイベントトリガーの比較は以下となります。

Cloud Functions AWS Lambda
オブジェクト作成 google.storage.object.finalize s3:ObjectCreated:*
オブジェクト削除 google.storage.object.delete s3:ObjectRemoved:*
オブジェクトアーカイブ時 google.storage.object.archive

※versioning有効化バケットのみ

s3:ReducedRedundancyLostObject
オブジェクトメタデータ更新 google.storage.object.metadataUpdate

AWS Lambdaの場合、Metadataを編集(追加)すると、ObjectCreatedでLambda Functionsが呼び出される。(Putだとトリガーは発動しない)

GCS オブジェクトのメタデータ更新された場合も検知することができる。

 $ curl -X PATCH --data-binary @meta.json -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" -H "Content-Type: application/json" "https://www.googleapis.com/storage/v1/b/[gcs bucket]/o/[object]" 

GCS オブジェクトのメタデータ更新時もFunctionsが動作します。

 

 

 

 

 

–stage-bucket も指定不要になり、管理外のバケット(?)にzipをアップロードしているようにみられる。gcf-upload-us-central1-<ランダム文字列>。cliでデプロイすると、sourceUploadUrlに表示されます。

2018年2月18日
から hiruta
ACME v2でLet’s Encryptのワイルドカード証明書を発行してみました。 はコメントを受け付けていません。

ACME v2でLet’s Encryptのワイルドカード証明書を発行してみました。

ACME v2用のacme.shが試せるようになりました。

ACME v2はacme.shのマスタブランチにマージ済みので、(https://community.letsencrypt.org/t/acme-v2-is-merged-in-to-master-branch-of-acme-sh/52242
下記でACME v2用のスクリプトを取得できます。

 curl https://get.acme.sh | sh 
 acme.sh --test --dns --issue -d *.totalsolution.biz 

_acme-challenge.totalsolution.bizのTXTレコードを更新したあと、renewコマンドを実行する

 acme.sh --renew -d *.totalsolution.biz 

gcloud compute ssl-certificates createで証明書を登録

ACME v1と変わらず利用できました。


ただし、ACMEv2用のルート証明書は、現状ブラウザの信頼済みストア証明書ではないので、
2/27に、production V2 API endpointが使用されるまでは、テストのみで試しておくのがいいかと。

https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605

ACME v2正式リリースは遅れる見込み。

https://community.letsencrypt.org/t/acmev2-and-wildcard-launch-delay/53654

2018年2月17日
から hiruta
Cloud KMSによるBigQuery dataプロテクト #gcpug はコメントを受け付けていません。

Cloud KMSによるBigQuery dataプロテクト #gcpug

CloudKMS keyによるBigQuery データセット保護が、generally availableになりました。

一部制限があるので注意が必要です。

  • CloudKMS keyのリージョンとBigQuery データセットが同じである必要がある
    • CloudKMS keyにはglobal、マルチリージョン(us、asia、europe)には対応していない

Cloud KMS keyとBigQueryのデータセットが異なると以下エラーとなります。

The location
for the specified Cloud KMS key is us-central1. This location is not supported
for the BigQuery dataset location EU. Please select a Cloud KMS key in one of
the supported Cloud KMS locations: europe-west1, europe.

Encrypter/Decrypter roleをもったService Accountを登録する必要があります。

Service Account名は、GCPのプロジェクトにより異なります。bq show –encryption_service_accountで確認することができます。

このService Accountを削除してしまうと、Cloud KMSに紐づいたデータセットに対して、アクセスできなくなります。

 bq load --destination_kms_key projects/XXXXXXXXXXXXXXXXXXX/locations/us-central1/keyRings/bqprotectkey/cryptoKeys/key testdataset.emi010000_2 gs://upload_bucket_us/emi010000.csv schema.json
 bq query --use_legacy_sql=false --destination_kms_key projects/XXXXXXXXXXXXXXXXXXX/locations/us-central1/keyRings/bqprotectkey/cryptoKeys/key " SELECT name FROM testdataset.newtable "

bq copyにより、CloudKMS keyを紐づいたまま、テーブルをコピーすることが可能です。

最近対応したDDLでもCloudKMSを有効化できます。CloudKMS keyを変更することも。

 

As BigQuery provides managed storage, long-term inaccessible data is not compatible with BigQuery’s architecture. If the Cloud KMS key of a given BigQuery table is not available and not accessible for 60 consecutive days, BigQuery may choose to delete the table and its associated data. Before the data is deleted, BigQuery will send an email to the email address associated with the billing account at least 7 days before the deletion.

Cloud KMS keyがavailableでない場合、60日連続して続いた場合、データが削除されるかもしれない。53日前にはメールで通知があるようだが。

 

 

2017年12月3日
から hiruta
インターリージョンVPCピアリング #aws #jawsug はコメントを受け付けていません。

インターリージョンVPCピアリング #aws #jawsug

インターリージョンVPCピアリングがサポートされたので、スループットを計測してみました。

インターリージョンVPCピアリングのサポートのお知らせ

現状東京リージョンは対応していないので、USオレゴン(us-west-2)とUSオハイオ(us-east-2)間になります。

インスタンスタイプは、t2.medium(オハイオだとm3.mediumが使えない。。)、計測ツールはiperf3を使いました。

まずは、VPC Peering経由しない場合

 [ 4] 0.00-10.00 sec 72.2 MBytes 60.6 Mbits/sec 131 sender
[ 4] 0.00-10.00 sec 70.6 MBytes 59.2 Mbits/sec receiver
 [ 4] 0.00-10.00 sec 72.2 MBytes 60.6 Mbits/sec 131 sender
[ 4] 0.00-10.00 sec 70.6 MBytes 59.2 Mbits/sec receiver
[ 4] 0.00-10.00 sec 96.3 MBytes 80.7 Mbits/sec 214 sender
[ 4] 0.00-10.00 sec 94.7 MBytes 79.4 Mbits/sec receiver

次に、VPC Peering経由

 [ 4] 0.00-10.00 sec 79.1 MBytes 66.3 Mbits/sec 302 sender
[ 4] 0.00-10.00 sec 77.4 MBytes 64.9 Mbits/sec receiver
 [ 4] 0.00-10.00 sec 52.3 MBytes 43.9 Mbits/sec 227 sender
[ 4] 0.00-10.00 sec 50.4 MBytes 42.3 Mbits/sec receiver
 [ 4] 0.00-10.00 sec 65.8 MBytes 55.2 Mbits/sec 310 sender
[ 4] 0.00-10.00 sec 63.9 MBytes 53.6 Mbits/sec receiver

上記の通り、Peering通さないほうが良くなる結果となった。internet gatewayを出ないので早くなると予想したが予想とは違う結果になった。

VPC Peeringの経路は1ホップであることは確認。

traceroute 172.22.1.114
traceroute to 172.22.1.114 (172.22.1.114), 30 hops max, 60 byte packets
1 ip-172-22-1-114.us-west-2.compute.internal (172.22.1.114) 69.081 ms 71.186 ms 70.115 ms

 

GCPのus-central1とus-west1間のスループットを追加しました。

 [ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 825 MBytes 692 Mbits/sec 1 sender
[ 4] 0.00-10.00 sec 824 MBytes 691 Mbits/sec receiver
 [ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 638 MBytes 535 Mbits/sec 41 sender
[ 4] 0.00-10.00 sec 637 MBytes 534 Mbits/sec receiver
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 827 MBytes 694 Mbits/sec 0 sender
[ 4] 0.00-10.00 sec 826 MBytes 693 Mbits/sec receiver

AWSに比べて、リージョン間でも一桁違うスループットを記録。

 

2017年12月2日
から hiruta
S3 Selectを試してみた #aws #jawsug はコメントを受け付けていません。

S3 Selectを試してみた #aws #jawsug

re:invent 2017で発表されたS3 Selectのpreview が通ったので、試してみました。

※S3 Selectはプレビュなので、将来仕様が変わる場合があります。

試したのは、Python SDK 2.7になります。

必要なモジュールは、boto3と、下記からダウンロード、カレントフォルダに展開する必要があります。

 wget http://s3select.s3-website-us-east-1.amazonaws.com/public/python/aws-python-sdk-s3-select-preview-1.0.0.zip

サポートされているリージョンは、下記となっており、東京リージョンのS3 bucketは対応していません。

米国東部 (バージニア北部)、米国東部 (オハイオ)、米国西部 (オレゴン)、欧州 (アイルランド)、およびアジアパシフィック (シンガポール)

S3 Selectをサポートしていないリージョンを指定すると、下記エラーメッセージが表示されます。

 botocore.exceptions.ClientError: An error occurred (MethodNotAllowed) when calling the SelectObjectContent operation: The specified method is not allowed against this resource.

サンプルコード


import boto3
from s3select import ResponseHandler
import os
import sys

class PrintingResponseHandler(ResponseHandler):
def handle_records(self, record_data):
print(record_data.decode('utf-8'))

args = sys.argv;

CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
MODELS_DIR = os.path.join(CURRENT_DIR, 'models')
os.environ['AWS_DATA_PATH'] = MODELS_DIR

expression = args[1]

s3 = boto3.client('s3','us-west-2')
response = s3.select_object_content(
Bucket='xxxxxx',
Key='401307influenza.csv',
SelectRequest={
'ExpressionType': 'SQL',
'Expression': expression ,
'InputSerialization': {
'CompressionType': 'NONE',
'CSV': {
'FileHeaderInfo': 'IGNORE',
'RecordDelimiter': '\n',
'FieldDelimiter': ',',
}
},
'OutputSerialization': {
'CSV': {
'RecordDelimiter': '\n',
'FieldDelimiter': ',',
}
}
}
)

handler = PrintingResponseHandler()
handler.handle_response(response['Body'])

所感

  • S3でGZIPされたファイルに対しても、実行することが可能
  • CSVの場合、Ⅰ行目を抜いて、COUNTしてくれました
  • AVG、SUM、MAX、MINなども使えるとなっているが、現状使い方が悪いのかシンタックスエラーになってしまいます。(GROUP BYは未対応)
  • select s._4 from S3Object where _4 = ‘2017’ のようにselect句とwhere句に同じフィールドで実行するとエラーとなる
 botocore.exceptions.ClientError: An error occurred (InternalError) when calling the SelectObjectContent operation (reached max retries: 4): We encountered an internal error. Please try again.

日本語も表示することは可能(UTF-8に限られます)

現状暗号化されたS3 Objectには対応していない。

暗号化させて、S3 にアップロードして、

 aws s3api put-object --bucket xxxxx --key 401307influenza2.csv --body  401307influenza2.csv --server-side-encryption AES256 --debug

S3 Selectしたところ、以下エラーが返ります。

 botocore.exceptions.ClientError: An error occurred (UnsupportedEncryptionMode) when calling the SelectObjectContent operation: We do not support server side encryption. Please check the service documentation and try again.

あと、検索はフルスキャンになるか情報がなかったので、不明