/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

2019/02/01 Parquet ファイルと Glue DataCatalog のスキーマ差異の問題など

AWS Glue と戯れる日々なのですが、SparkSQL の扱い方がわかったところでまたいくつか問題が。

Parquet とテーブルスキーマのフォーマット差異

S3 に書き出したファイルを Glue の DataCatalog を経由して Athena や Redshift から読み込もうとすると、Athena からは読み込めるけれど Redshift からは読み込めない問題が。

https://forums.aws.amazon.com/thread.jspa?threadID=257680

Parquet のスキーマと DataCatalog で定義したテーブルスキーマとの間で整合性が取れない場合に、こういったエラーがでるのですが、今回はAthena からは読み込めるけれど Redshift からは読み込めないという中途半端な状態でした。テーブル定義では bigint を指定していたのですが、Parquet で書き出すときに int 型になっていて、その差異を Athena は吸収してくれたのですが Redshift では型が違うということでエラーになっていたのが原因でした。

Glue で書き出すと、テーブルへの INSERT ではなく Parquet ファイルの書き出しとなるので、今回のように型を間違うことは頻発しそうです。SparkSQL を一段下げて

SELECT
  CAST(col1 AS int) col1,
  CAST(col1 AS bigint) col2
FROM ...

のように、明治的にキャストしてあげると間違いも減りそうです。

空テーブルを DynamicFrame にできない

Glue の DataCatalog からデータを読み込み、DynamicFrame にするところで、対象のテーブルやパーティションが空だと Unable to infer schema for Parquet. It must be specified manually. というエラーが発生してしまう問題にも出くわしました。

stackoverflow.com

空テーブルをわざわざ DynamicFrame にする必要はないのですが、読み込むテーブルなどをパラメタ化したいと思っていて調査していましたが、テーブルのデータを読み込むところでエラーになってしまいます。これは回避方法がなさそうなので、 isEmpty メソッドなので例外を明示的に処理するなどしか対処法はなさそうです。

2019/01/22-23 AWS Glue Crawler が struct をカラムに持つテーブルに使いづらい

AWS Glue を色々と触っているのですが、どうにも正しい使い方がよく分からなくなってきました。

Glue Job で Parquet フォーマットで書き出して Athena から読み込みたいのですが、パーティションによってキー数が大きく異なる JSON 形式のカラムがあるためにうまくいきません。統一的に扱うなら string にして保存してしまえば良いんですけど、そうすると SparkSQL で上手く扱えない(SparkSQL で string を JSON として扱う方法があれば教えてください ありました、get_json_object 関数を使うことで string 形式の JSON からバリューを抜き出すことができました。)。

Glue Job で string ではなく struct で書き出すと、Glue Crawler がパーティションごとに異なるスキーマを生成してしまい、テーブル全体としてスキーマが一致しない(incompatible) ので Athena で読めない。その場合のエラーは HIVE_PARTITION_SCHEMA_MISMATCH なので、回避方法はあります:

https://forums.aws.amazon.com/thread.jspa?messageID=805011

Athena と AWS Glue を併用する際のベストプラクティス - Amazon Athena

stackoverflow.com

ただこれを回避すると、別の HIVE_CANNOT_OPEN_SPLIT というエラーが。私の環境では Schema mismatch, metastore schema for row column contents has 185 fields but parquet schema has 149 fields と出ます。色々 Glue Crawler 上で試しましたが回避方法は見つかっていません。

adtech-blog.united.jp

結局、struct を使うのが問題の根源なので、 string か、せめて map<string,string> のようなもう少し汎用的な形で保存できればよいなと思っています。これなら Crawler ではなく MSCK REPAIR TABLE コマンドでパーティション追加するだけでいけるはず。ただこれを Glue Job(PySpark) で実現する方法がまだ分かりません。

Glue は便利そうだなと思っていましたが、Crawler のようなデータ管理をよしなにやってくれるサービスが上手くいかないと逆に検証に時間を取られて徒労に終わってしまうなぁと思った今日この頃。。結局 Spark でのデータ変換をきちんと勉強して地道に変換した方が早い気がしています。

追記

上で記載しましたが、 get_json_object という関数を利用することで string 形式の JSON からバリューを抜き出すことができました。とりあえずこれで、 Glue Job で string 形式で保存した上で、あとから SparkSQL でアクセスすることができます。

API ドキュメントはこちら。先週結構探したつもりだったんですが、今日さがしたらすぐに見つかりました。。

spark.apache.org

2019/01/15 Glue における SQL 中心アーキテクチャ ETL、他

昨日居酒屋で飲んでいたら(かぶら屋 美味しいです、おすすめ)、隣の席の人が UberEATS の使いすぎで他の方から怒られていました。僕の友人でも UberEATS や LINE デリマを良く使う人はいるので、別にいいんじゃないかなと思ったら、どうやら人はタクシーやデリバリーなどの細かい出費の積み重ねで借金をしてしまった?ようです。

借金とは言わないまでも、昔はなかった通信費は今やもはや固定費になっているし、便利さと引き換えに可処分所得は減っているという記事をどこかで見たような気がしたなぁと思った週末でした。

「AWS Glue と SQLのみで、サクッとETL(Extract、Transform、Load)するJobを作成する」

dev.classmethod.jp

Glue のジョブはGlue が提供する Transform を利用しないといけないと思っていましたが、 入出力の雛形ジョブだけ Glue に用意して、SparkSQL を外部から設定できるようにすれば「SQL中心アーキテクチャ」による ETL が簡単に実現できるといった内容です。

外部(S3 上に置いておく想定)の設定ファイルは以下のようなものです:

{
    "source_database":"default", 
    "source_table":"elb_parquet_20150101", 
    "target_s3_url":"s3://<mybucket>/tmp/", 
    "target_format":"parquet", 
    "sql":"SELECT elb_name, count(*) as request_count FROM stagingtable group by elb_name order by elb_name"
}

これを S3 から読み込んで JSON パースして Glue 上で SparkSQL を実行します。これだと1テーブルしか扱えないので複数テーブル与えられるようにフォーマットを変更したいですが、これなら SQL だけ書ければ ETL 処理が実現できるので扱える人が増えそうです。

ただ、ETL ジョブの依存関係を解決しようとすると Glue だけでは難しそうです。Glue にも「トリガー」があって、他のジョブへ依存するジョブを作成できるのですが、パラメータレベルでは対応していないので、上のように SQL をパラメータ経由で渡すような運用だと「トリガー」では対応できません。

「Glueの使い方的な⑦(Step Functionsでジョブフロー)」

こちらも分かりやすい記事でした、Glue + Step Functions の組み合わせです。Glue の呼び出しには Lambda を使っています。

qiita.com

ワークフローが巨大だと GUI でも JSON でも扱いづらそうなので、ある程度意味のあるまとまりでまとめておく程度にした方がよさそうでしょうか。。CloudWatch を使えばワークフロー間の連携も実現できそうなので引き続き調べます。

2019/01/11

ご挨拶が遅れました、あけましておめでとうございます。

年の始まりはいつも不思議な出来事があって、今年はこういう感じなのか、と思うことがあります。今年は変わったことがちらほら周りで起きていて、変化の年になるのかもしれません。よい方向に変化するように少しずつの積み重ねで勉強だけは一層取り組もうと思います。去年部署移動してチーム開発が始まるかもしれないので、今年はソフトウェア設計についてもう少し詳しくなりたいです。

知り合いから語学の才能があるとよく言われるので、そちらももっと活かしたいなぁという思いが最近強いのですが、学習は継続しつつどこかキャリア内でも使えればよいなぁと思う昨今。

AWS Glue

Glue について色々調べているのでメモ。

qiita.com

Spark の DataFrame との違いが冒頭に書いてあります。

docs.aws.amazon.com

docs.aws.amazon.com

Spark

Spark 直接扱ったことがなくて、Glue で Python から Spark を動かすと大量に小さいファイルができてしまいました。Hive のように適切なファイルサイズでファイル出力する方法はないかと調べていましたが、どうやら難しいようです。

stackoverflow.com

概念的には重要なものの、Spark アプリケーションを構築する際は DataFrame, DataSet を利用すべきと書いてあります。理由としては「時代遅れ」「使いづらい」「速度が遅い」と3つ挙げられていました。

dzone.com

ついでながら RDD の復習・・・

dev.classmethod.jp

Step Function

まだ読んでいないけれど、Glue のジョブキッカーとして使えそう

noise.getoto.net

2019/01/11

ご挨拶が遅れました、あけましておめでとうございます。

年の始まりはいつも不思議な出来事があって、今年はこういう感じなのか、と思うことがあります。今年は変わったことがちらほら周りで起きていて、変化の年になるのかもしれません。よい方向に変化するように少しずつの積み重ねで勉強だけは一層取り組もうと思います。去年部署移動してチーム開発が始まるかもしれないので、今年はソフトウェア設計についてもう少し詳しくなりたいです。

知り合いから語学の才能があるとよく言われるので、そちらももっと活かしたいなぁという思いが最近強いのですが、学習は継続しつつどこかキャリア内でも使えればよいなぁと思う昨今。中国語も簡単なものなら少し読み書きできるようになってきました。

勉強会レポート:「Docker/Kubernetes 実践コンテナ開発入門」の著者を招いてハンズオンをしました

社内勉強会の様子をブログにまとめました。 Docker, Kubernetes のハンズオンを社内で実施したのでその様子です。

developers.cyberagent.co.jp

会社が大きいと色々な領域でのプロフェッショナルがいて、今回のようにご教示いただけるのはとてもありがたいです。部署移動して本社ビル(?)に移ったのですが、様々な変化はありつつ、こういった勉強会に参加しやすくなるのは純粋に嬉しいです。

メモ

AWS Glue

Glue について色々調べているのでメモ。

qiita.com

Spark の DataFrame との違いが冒頭に書いてあります。

docs.aws.amazon.com

docs.aws.amazon.com

Spark

Spark 直接扱ったことがなくて、Glue で Python から Spark を動かすと大量に小さいファイルができてしまいました。Hive のように適切なファイルサイズでファイル出力する方法はないかと調べていましたが、どうやら難しいようです。割と一般的な問題のように思えるんですが、Parquet フォーマットのデータを吐き出してそこに Hive なり Athena で繋ぐのは間違っているんだろうか。。

stackoverflow.com

Step Function

まだ読んでいないけれど、Glue のジョブキッカーとして使えそう

noise.getoto.net

2018/12/14 AWS Glue と Lambda Architecture

クリスマスの雰囲気が好きなのですがいかんせん寒くなってきて、出かけるのが億劫になってきました。インフルエンザも流行りだしたようなので、そろそろマスクをしなければいけない季節でしょうか。

今日は分散処理周りで調べ物をしていたので、読んだ記事をご紹介します。

The Illustrated Children's Guide to Kubernetes

同僚がチャットで紹介していたのですが、分かりやすかったです。Kubernetes はまだ触ったことがなくて、今月末社内でセミナーがあるので予習代わり・・・にはさすがにならないですが。。ユーモラスがあって可愛らしい。

www.publickey1.jp

www.publickey1.jp

AWS Glue の事例

primeNumber さんの事例

primeNumber さんの AWS Glue 活用事例です。Kinesis Firehose から S3 へ書き込み、そのあとの集計結果をまた S3 へ書き込むことによって、Batch layer と Serving layer(データを閲覧するレイヤ)の分離ができています。

speakerdeck.com

フューチャーアーキテクトさんの事例

Glue での実際のコード例や、EMR との比較なども紹介されていて分かりやすいです。あまり実態がつかめていなかったのですが、おかげで Glue を具体的に理解することができました。入出力でのパフォーマンス計測の記事もあり、参考になります。

future-architect.github.io

future-architect.github.io

キャスレー社のブログ

ログをクロールしてテーブルを作成し、さらに整形する・・・といった流れを Glue で行う例が紹介されています。大規模データに対してはどうか、と最後に締めくくられているのでパフォーマンス検証は行えていないようですが、Glue の使い方を理解するにはとても役立ちます。

www.casleyconsulting.co.jp

Lambda Architecture

Lambda Architecture » λ lambda-architecture.net

昔先輩に説明されて、よく理解できなかったのですが、今読むと理解できました。上の AWS Glue を利用した事例でも Lambda Architecture の概念から説明がされています。

"Lambda" は「ラムダ計算」から名付けられているようです。データは Batch layer に貯め続けて、そこに対する純粋な関数があり、データに対する問い合わせも副作用がない関数であり、様々なところで純粋な関数が出てくるので、"lambda" とつけるのが適切であるということのようです。

面白半分で I think its just the letter 'Lambda'. It looks like the data is divided into two streams. なんていう人もちらほら見かけました。。データが二手に分かれる様がλの文字のようだ、ということですが、ちょっと無理があるような。

stackoverflow.com

2018/12/13 (公式ブログより)AWS Kinesis を利用したリアルタイム+バッチ集計

Amazon Kinesis および Amazon Athena を使用して VPC ネットワークのトラフィックを分析および視覚化する

AWS の公式ブログにて、以下の Kinesis と Athena を利用した分析基盤の例が紹介されていました:

aws.amazon.com

Athena のところは本質的ではないと思いますが、、Kinesis を利用することで、リアルタイム集計ときちんと管理されたデータに対するデータ集計の2つを扱うことが可能です。

S3 へは Kinesis Firehose で出力するのですが、 S3 で作成されるファイルのサイズを最大化するためにこのソリューションは 15 分間または 128 MB までバッファリング とありますので、リアルタイムとは行かずとも、ニアリアルタイムなデータを Athena で扱うことができそうです。

  • 上記例は VPC フローログ という AWS 側が収集したデータですが、外部から流れてくるデータに対しての精査などはどこで行えば良いか
  • 日次などの集計をどうやって扱うと効率的か

まだ調べ始めたばかりなので各コンポーネントに対する理解が足らず、引き続き調べます。