AWSのAthenaでS3のファイルを分析しようとしたらトラブった話
トラブル概要
S3にあるtsvファイルをAthenaでテーブル化してQuickSightで可視化したい。
CREATE EXTERNAL TABLE `2019101919_sample_data`(
`created_at` string,
`updated_at` string,
`id` string,
`title` string,
`user` string,
`likes_count` bigint,
`comments_count` bigint,
`page_views_count` string,
`url` string,
`tags` string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
's3://test-playground/2019/10/2019101919_sample_data.tsv'
このクエリ文自体は成功する。
が、なぜか結果が返ってこない。
解決策
Zero records returned
というエラーが出ているが、そもそも結果をよくみるとData scanned: 0KBと出ている。これはLOCATION
句のS3のパスが間違っているのが原因であるらしい。
別にファイルの場所は間違ってないし、アクセス権限も問題ないんだが…
公式のマニュアルをよくみてみる。
ファイルの場所を指定するために、ファイル名、アンダースコア、ワイルドカード、または glob パターンを使用しないでください。
Amazon S3 のテーブルの場所 - Amazon Athena
Athenaでファイル名をダイレクトに指定するのはダメ!
ということで分析したいファイルの場所をどこか適当なフォルダ配下に移行する。
例えば ※後述s3://test-playground/2019/10/19/19/data.tsv
など
例えば2019/10/19 19:00のデータを
s3://test-playground/sample-data/dt=2019-10-19/19.tsv
というように格納する。
CREATE EXTERNAL TABLE `2019101919_sample_data`(
`created_at` string,
`updated_at` string,
`id` string,
`title` string,
`user` string,
`likes_count` bigint,
`comments_count` bigint,
`page_views_count` string,
`url` string,
`tags` string)
PARTITIONED BY (
`dt` string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t' -- ここがただの空白になっていないことを確認する
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
's3://test-playground/sample-db/dt=2019-10-19/' -- ここをフォルダ名にする!
これでうまく結果が返ってくるようになった。
ちなみにtsvの区切り文字だが、Athenaのコンソール画面からテーブル作成するとただの空白になっているので注意。
学び
GlueのデータカタログをAthenaに統合する場合は注意!
そもそも何でこんなエラーにぶち当たったかというと、
- Lambdaで一時間に一回データを収集してS3に保存
- GlueでS3のファイルを全部テーブル化
- Athenaで分析
こういうシナリオだった。
この場合Glueで素直にクローラーを作ってテーブルを作ると1ファイルにつき1テーブル作成されてしまう。
Glueのコンソールからはしっかりテーブル作成できているように見えるが、いざAthenaで分析しようとすると結果が返ってこないというエラーにぶち当たるわけだ。
データを格納するときにHiveのパーティション形式で保存すると便利
※tokusyuさんのコメントを反映しました。
そもそものデータ収集の際のoutput先を下記のように指定しておくと便利。
s3://<bucket>/<year>/<month>/<day>/<hour>/data.tsv
s3://<bucket>/<適当なディレクトリ名>/dt=<year>-<month>-<day>/<hour>.tsv
こうしておけば、データを格納すると同時にパーティショニングも実行できる。
あとはAthenaから下記のようにパーティションをロードすればOK。
MSCK REPAIR TABLE <テーブル名>;
パーティション分割を行うことでデータのスキャン量が削減できる。そのため時間短縮やコスト削減につながるのでぜひやっておきたい。
Author And Source
この問題について(AWSのAthenaでS3のファイルを分析しようとしたらトラブった話), 我々は、より多くの情報をここで見つけました https://qiita.com/si1242/items/567e8d9409b1cb0dde41著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .