【S3】AWSのデータレイク機能まとめ

# はじめに

本記事では、AWSにおいてデータレイクを構築してデータ分析に活用するためのサービスを紹介します。AWSにおいては基本的にS3がデータレイクにおける基盤となるため、以下の記事も併せて参照ください

https://qiita.com/c60evaporator/items/da47620d69f84a9be7dc

## データレイクとは

データレイクとは構造化、非構造化を問わず様々な形式のデータを大量に保管するための仕組みで、主に**ビッグデータ分析**に用いられます。

ビッグデータ分析用のデータ保管方法には、他にもデータウェアハウス（DWH）が挙げられますが、DWHは構造化されたデータベース形式でデータを保持するのに対し、データレイクはCSVやテキストファイル、画像のような非構造化データも保存できる事が特徴です。

ビッグデータ分析の特徴として、数千万行（レコード）以上の大容量データを分析対象として扱う事が挙げられます。このような大容量データを扱うことで、以下のようなメリットとデメリットが生じます。

### データレイクとS3

以下公式ドキュメントで述べられているように、AWSにおいては基本的にS3がデータレイクの基盤の役割を果たします。S3のバケット状に分析対象となるデータを蓄積する事で、後述する各種サービスでの分析を実現できます。

https://aws.amazon.com/jp/big-data/datalakes-and-analytics/datalakes/?nc=sn&loc=4

### データレイクのメリット

データレイクを使用することで、以下のメリットを得る事ができます。

- 大量のデータを分析対象とする事で、詳細な分析や信頼性の高い分析が可能となる（ビッグデータ分析のメリット）
- 大量のデータを必要とする深層学習等のアルゴリズムを適用しやすくなる（ビッグデータ分析のメリット）
- ETL等のデータ蓄積時の前処理が不要となるため、分析基盤の開発コストを低減できる（DWHと比べたデータレイクのメリット）

3つ目のメリットについて補足ですが、[こちらの記事](https://www.talend.com/jp/resources/what-is-data-lake/)に記述されているように、DWHはデータの蓄積時にスキーマを定義する必要があり（Schema on Read）、同時にデータをテーブル形式に変換するバッチ処理（あるいはストリーミング処理）を走らせる必要があります。よってこれらの仕組み（データパイプラインやETLと呼ばれます）を事前に構築する必要があり、データ蓄積を始めるまでに大きなコスト・時間が掛かります。一方で**データレイクはデータを加工せずにそのまま蓄積**する、「加工は後でやれば良い」という考えに基づいたシステムのため、初期投資が少なくて済むというメリットがあります（その代わり、分析時の前処理の手間は増えます）

2023年4月現在、ビッグデータ分析自体がやや下火となっている状況ですが、ChatGPTを始めとした多くのデータを必要とするAIサービスがブームとなりつつあるので、個人的にはまた盛り上がる可能性があるのではないかと考えています。

### データレイクのデメリット

- 分析時に大量のデータの取得が必要なため、所要時間が長くなる（ビッグデータ分析のデメリット）
- 分析時に大量のデータを取得が必要なため、クラウドサービス等の通信コストが増大する（ビッグデータ分析のデメリット）
- 構造化が不十分な形式（CSV, テキスト等）でデータが保存されるため、分析時の前処理に手間が掛かる（DWHと比べたデータレイクのデメリット）

上記のようにデータレイクを活用する際は、**適切な工夫をしないと開発・運用両面で所要時間やコストが膨大**なものとなってしまいます。

このような事態を防ぐため、「適切な工夫」に相当するサービスが、各社クラウドには準備されています。

## クラウドのデータレイク向けサービス

上記のデメリットを防ぐため、各社データレイク向けサービスは主に以下の機能を提供しています。

- クエリを用いて大量データの中から**一部の必要データのみを取得**し、**所要時間・通信コストを低減**する
- CSV等の**構造化が不十分なデータ**を、RDBのような**SQLクエリで一括で扱える**ようにする

以下で紹介するAWSの4サービスも、上の2機能を提供することを基本としています。

## S3のデータレイク関連サービス

AWSにおいてはS3がこのデータレイクの役割を果たしており(Hadoop互換の分散ファイルシステムに対応)、**S3に格納された**テキスト、CSV、Parquet形式等の**データと以下のサービスを組み合わせる**事で、**大量データに対する高速分析**を実現する事ができます。

|名称|概要|ユースケース|
|---|---|---|
|[**S3 Select**](https://qiita.com/c60evaporator/items/a926097d7275f07fef03)|**S3に保存された**CSV, JSON, Parquet形式**データに対しSQLクエリ**によるデータ取得・分析が可能|簡単なデータ分析|
|[**Athena**](https://qiita.com/c60evaporator/items/2695f0ceeccbbda1bac9)|**S3に保存されたデータに対しSQLクエリ**によるデータ取得・分析が可能 (**S3 Selectより高機能**)|高機能なデータ分析|
|[**Redshift Spectrum**](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379)|**S3に保存されたデータ**に対し、**Redshiftによる直接クエリ**実行・分析が可能|Redshiftの技術資産を活用したデータ分析|
|[**EMR**](https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-what-is-emr.html)|**Apache Spark**等の分散データ処理フレームワークを利用して**高速ビッグデータ分析**が可能|Sparkを活用した高速データ分析|

|特徴|S3 Select|Athena|Redshift Spectrum|EMR|
|---|---|---|---|---|
|コンソールからのクエリ実行|○|○|○|×|
|SDKによるクエリ実行（Python等）|○|○|○|○|
|CLIからのクエリ実行|○|○|△※|×|
|HTTPリクエストとREST APIによるクエリ実行|○|△※|△※|×|
|Sparkによる分散処理|×|○|×|○|

※機能自体は存在するようですが、現状では操作が複雑かつ該当する公式ドキュメントが存在せず、実装が困難な状況です

また、上記サービスはデータレイク（S3）内のデータをクエリして分析することに主眼を置いていますが、[**AWS Lake Formation**](https://aws.amazon.com/jp/lake-formation/)と呼ばれるサービスを用いることでデータのカタログ化やアクセス制御の一元化を実現でき、より利便性を高める事ができます。

それぞれのサービスを解説します

## S3 Select

S3 Selectは、S3に保存されたCSV, JSON, Parquet形式のデータ (GZIPやBZIP2による圧縮データでもOK)に対して、**SQLクエリによるデータ取得**ができる機能です。

今回紹介するサービスの中で**最も手軽**に利用できるため、**S3内のテキストやCSVファイルの内容**を**コンソールから簡単に閲覧、分析**したい際に便利です。

単純にデータの集計や分析が出来る事以外にも、クエリでフィルタリングした後のデータのみを取得できるため、通信コストやデータ取得時間を抑えられるというメリットもあります。

コンソールだけでなく[Rest APIやSDK経由でプログラムからも実行できる](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/using-select.html)ので、S3からのデータ取得時間・コストを抑えたい場合の選択肢の一つとして検討しても良いかと思います。

詳細は以下の公式ドキュメントを参照ください

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/selecting-content-from-objects.html

なおS3 Selectは厳密にはAWSの独立したサービスではなく、S3内の一機能となります。

## Athena

S3 Selectと同様に、**S3に保存されたデータに対してSQLクエリによるデータ取得**ができるサービスですが、**S3 Selectよりも高機能**で、以下のような違いがあります。

- CSV, JSON, Parquet形式以外にも、txt等多数のデータ形式に対応
- 複数のファイル（オブジェクト）に一括でクエリ実行できる（S3 Selectは1ファイルのみ）
- ORDER BYやGROUP BYのような複雑なクエリにも対応
- 対応する圧縮形式もS3 Selectより多い
- S3とは独立したサービスのため、S3以外のデータソースにも対応 ([AWS Glueデータカタログ](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/catalog-and-crawler.html)により接続)

**S3 Selectと比べるとパフォーマンス面でも機能面でもグレードアップ**しており、また**サーバーレス**のためRedshiftよりも気軽に低コストで使えるというメリットを得られ、Webアプリのログ解析等のユースケースが想定されています。

今回紹介する4つのサービスの中でも、**お手軽さと性能のバランスが取れたサービス**と呼べるでしょう。

詳細は以下の公式ドキュメントを参照ください

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/using-athena-sql.html

## Redshift Spectrum
**Redshift Spectrum**は、**S3等に保存されたデータに対して直接Redshiftのクエリを実行**できる機能です。

AWS上に分析用DBを構築する場合、データウェアハウス (DWH)であるRedshiftを用いる事が第一の選択肢となります。
S3上のデータをRedshiftで分析する場合、旧来はデータを整形してRedshift上のテーブルにコピー [(Extract, Transform, Load = ETL)](https://pages.awscloud.com/rs/112-TZM-766/images/AWS_ETL_services_tips_202107.pdf)する必要がありましたが、Redshift Spectrumを用いることでこのようなETLシステム構築の手間を省くことができます。

**ログ等の大規模データの分析**に用いるという点で**ユースケースがAthenaと近く**、両者の使い分けには以下の記事が参考となります。

https://www.integrate.io/jp/blog/amazon-redshift-spectrum-vs-athena-a-detailed-comparison-ja/

まとめると**以下のようなメリットデメリット**が得られそうです。

||Redshift Spectrum|Athena|
|---|---|---|
|メリット|・Redshiftの機能をそのまま活用できる（Redshiftユーザなら学習コスト低）<br>・高負荷時も安定動作する|・サーバーレスのためクラスタの維持費が掛からない<br>・管理がシンプル|
|デメリット|・クラスタを常時起動するための維持費がかかる<br>・管理にやや手間が掛かる|・Athena独自機能に対する学習コストが掛かる（Redshiftを既に使用している場合）<br>・高負荷時は動作が遅くなることがある|

上記だけだと分かりづらいかと思いますが、Redshift Spectrumは**クラスタの維持費だけで5万円/月以上掛かる**ので、かなり**大規模なシステムでなければAthenaの方がコストパフォーマンスが良い**でしょう。

一方で[こちらの記事](https://qiita.com/c60evaporator/items/2695f0ceeccbbda1bac9#スクリプト例)で述べるようにPython SDKでAthenaを利用する際、クエリの出力が数千行を超えるとレスポンスが分割されて実行速度が落ちるため、**大きな出力をPythonで受け取りたい場合**は**Redshift Spectrumを使用した方がパフォーマンスを維持できる**でしょう。

Redshift Spectrumの詳細は、以下の公式ドキュメントを参照ください

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-using-spectrum.html

なお、サーバーレスかつDWHであるBigQueryの技術資産を流用できる、ある意味両者の良いとこ取りとも言えるGoogle Cloudの**BigQuery Omni**も、マルチクラウドを許容できるのであれば選択肢に入れても良いかと思います。

https://blog.g-gen.co.jp/entry/bigquery-omni-trial

### ※Redshift Serverless
2022/7より、RedshiftのサーバーレスバージョンであるRedshift Serverlessの一般公開が開始されたようです。今のところRedshift Spectrumには対応していなさそうですが、BigQuery Omniのようなサーバレス運用ができるよう、将来的な対応を期待したいところです。

https://qiita.com/hashimoto_mana/items/24cc25c5f9e2e44618bc

## EMR
EMRは、**Apache Spark**、Apache Hive、Presto 等の分散データ処理フレームワークを利用して高速ビッグデータ分析を実現できるサービスです。

EMRではクラスターと呼ばれる処理用のノード (実体はEC2インスタンス)を複数立ち上げ、これらを分散処理フレームワークで制御 ([YARNの記事](https://qiita.com/keigodasu/items/09f7e0a15d721b0b5212)が参考になります)する事で、分散高速処理の恩恵を受けられるサービスです。
狭義の「データレイク」はこのような分散処理フレームワークを指すことが多いので、Redshiftと並んでAWSにおけるビッグデータ分析の王道のサービスと呼べるでしょう。

これだけ聞くと仰々しく感じますが、SparkはPython(PySpark)等の**SDKを利用する事で簡易に分析スクリプトを作成**する事ができるため、**手軽に数千万行クラスのデータの高速分析**を実現する事ができます。

詳細は、以下の公式ドキュメントを参照ください。

https://docs.aws.amazon.com/ja_jp/emr/latest/ManagementGuide/emr-what-is-emr.html

## AWS Lake Formation

https://dev.classmethod.jp/articles/20220111-datalake-build/

# 実践方法
実際にコンソール、およびPython SDK (Boto3)から分析クエリを実行する方法を解説します

## 前準備

### 使用するデータ
[こちらの記事で取得した](https://qiita.com/c60evaporator/items/92d0ebde001f568f2707)IoTデータを、年ごとにフォルダ分けし、月ごとにCSVファイルにまとめて以下のフォルダ構成 (プレフィックス)でS3バケットに格納して使用します

```
バケット名
  └──sensors
      └──per_month
          ├─2020
          │   ├─202008.csv
          │   :
          │   └─202012.csv
          ├─2021
          │   ├─202101.csv
          │   :
          │   └─202012.csv
          └─2022
              ├─202101.csv
              :
              └─202008.csv
```

コンソールでの表示例

![スクリーンショット 2023-03-19 2.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/2fcb4117-730d-7568-60bd-432f2e4fe886.png)

CSVファイルの中身は以下のようになっています ([参考](https://qiita.com/c60evaporator/items/92d0ebde001f568f2707#スキーマの作成))

```csv:使用するCSVファイル
_id,Date_Master,Date_ScanStart,no01_DeviceName,no01_Date,no01_Temperature,no01_Humidity,no01_Light,no01_Human_last,no01_HumanMotion,no01_TempSetting,no01_AirconMode,no01_AirVolume,no01_AirDirection,no01_AirconPower,no01_CumulativeEnergy,no01_Watt,no02_DeviceName,no02_Date,no02_Temperature,no02_Humidity,no02_Light,no02_Pressure,no02_Noise,no02_eTVOC,no02_eCO2,no03_DeviceName,no03_Date,no03_Temperature,no03_Humidity,no04_DeviceName,no04_Date,no04_Temperature,no04_Humidity,no05_DeviceName,no05_Date,no05_Temperature,no05_Humidity,no05_Light,no05_UV,no05_Pressure,no05_Noise,no05_BatteryVoltage,no06_DeviceName,no06_Date,no06_Temperature,no06_Humidity,no07_DeviceName,no07_Date,no07_Temperature,no07_Humidity,no07_BatteryVoltage,no08_DeviceName,no08_Date,no08_HumanLast,no08_HumanMotion,_partition
5f359f60de55bc0802637080,2020-08-14 05:15:00.000,2020-08-14 05:15:03.891,Nature_Remo_1,2020-08-14 05:15:06.167,28.2,64.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.17,548.0,Omron_USB_1,2020-08-14 05:15:07.093,27.48,71.54,111,1005.229,58.29,289,1650,Inkbird_IBSTH1_1,2020-08-14 05:15:10.068,27.91,68.21,Inkbird_IBSTH1_2,2020-08-14 05:15:12.706,31.49,63.15,Omron_BAG_1,2020-08-14 05:15:17.748,32.18,62.48,6.0,0.01,1006.3,39.8,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:15:21.384,26.53,75.28,SwitchBot_Thermo_1,2020-08-14 05:15:26.413,31.7,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:15:28.835,2020-08-13T20:14:14.000Z,1,Project HomeIoT
5f35a09092376c3d5d76612c,2020-08-14 05:20:00.000,2020-08-14 05:20:04.054,Nature_Remo_1,2020-08-14 05:20:06.294,28.2,62.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.22,360.0,Omron_USB_1,2020-08-14 05:20:07.249,27.45,68.86,108,1005.284,46.18,280,1638,Inkbird_IBSTH1_1,2020-08-14 05:20:12.872,27.93,66.46,Inkbird_IBSTH1_2,2020-08-14 05:20:17.417,31.4,63.06,Omron_BAG_1,2020-08-14 05:20:22.446,32.24,62.63,13.0,0.02,1006.3,38.61,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:20:25.224,26.51,74.69,SwitchBot_Thermo_1,2020-08-14 05:20:30.252,31.9,64.0,100.0,Sony_MeshHuman_1,2020-08-14 05:20:32.635,2020-08-13T20:20:14.000Z,1,Project HomeIoT
5f35a1ba291e40c5ea258ee3,2020-08-14 05:25:00.000,2020-08-14 05:25:04.460,Nature_Remo_1,2020-08-14 05:25:06.701,28.2,64.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.25,580.0,Omron_USB_1,2020-08-14 05:25:07.458,27.32,70.51,106,1005.352,44.38,259,1615,Inkbird_IBSTH1_1,2020-08-14 05:25:09.629,27.95,68.14,Inkbird_IBSTH1_2,2020-08-14 05:25:11.219,31.4,62.94,Omron_BAG_1,2020-08-14 05:25:21.290,32.15,62.87,25.0,0.03,1006.3,39.02,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:25:23.063,26.53,73.39,SwitchBot_Thermo_1,2020-08-14 05:25:28.090,31.8,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:25:30.343,2020-08-13T20:24:14.000Z,1,Project HomeIoT
5f35a2e24098c6e9f618daa4,2020-08-14 05:30:00.000,2020-08-14 05:30:03.594,Nature_Remo_1,2020-08-14 05:30:05.794,28.2,64.0,143.0,2020-08-13T20:08:42Z,0.0,28.0,cool,1,auto,power-on,2957.29,428.0,Omron_USB_1,2020-08-14 05:30:06.555,27.25,73.02,106,1005.377,43.66,265,1623,Inkbird_IBSTH1_1,2020-08-14 05:30:09.387,27.92,68.94,Inkbird_IBSTH1_2,2020-08-14 05:30:12.162,31.49,62.93,Omron_BAG_1,2020-08-14 05:30:17.203,32.14,62.77,32.0,0.02,1006.5,39.22,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:30:18.825,26.53,75.26,SwitchBot_Thermo_1,2020-08-14 05:30:23.865,31.7,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:30:26.573,2020-08-13T20:30:15.000Z,1,Project HomeIoT
5f35a41a90393b85364a6c71,2020-08-14 05:35:00.000,2020-08-14 05:35:04.370,Nature_Remo_1,2020-08-14 05:35:06.617,28.2,64.0,143.0,2020-08-13T20:34:01Z,1.0,28.0,cool,1,auto,power-on,2957.32,456.0,Omron_USB_1,2020-08-14 05:35:07.443,27.45,74.21,104,1005.468,57.8,244,1598,Inkbird_IBSTH1_1,2020-08-14 05:35:10.129,28.07,69.8,Inkbird_IBSTH1_2,2020-08-14 05:35:12.960,31.47,62.75,Omron_BAG_1,2020-08-14 05:35:18.000,32.06,62.93,48.0,0.02,1006.6,39.22,2.96,Inkbird_IBSTH1mini_1,2020-08-14 05:35:25.717,26.62,76.67,SwitchBot_Thermo_1,2020-08-14 05:35:35.787,31.7,65.0,100.0,Sony_MeshHuman_1,2020-08-14 05:35:38.204,2020-08-13T20:34:15.000Z,1,Project HomeIoT
:
```

### Python SDK環境構築
Python SDK (Boto3)をローカルPCから使用できるよう、事前に環境構築を実施する必要があります

ローカルPCから以下を参考にアクセスキーのAWS CLIへの登録と、boto3の動作確認を実施してください

https://qiita.com/c60evaporator/items/e1fd57a0263a19b629d1#awsのアクセス権限設定

なお、上記記事の`AmazonS3FullAccess`ポリシーでは、S3 Selectの操作しかできません（AthenaやRedshift Spectrumの操作には権限が足りません）。この場合の適切なポリシー付与方法は、以下の「アクセス権限の付与」および後述のAthenaやRedshiftの使い方をまとめた記事を参照ください。

### 必要なアクセス権限の付与

#### S3 Selectで必要なアクセス権限

以下を参照ください。

https://qiita.com/c60evaporator/items/a926097d7275f07fef03#アクセス権限の付与

#### Athenaで必要なアクセス権限

以下を参照ください。

https://qiita.com/c60evaporator/items/2695f0ceeccbbda1bac9#アクセス権限の付与

（※ちなみに、[公式で準備されている](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/managed-policies.html#amazonathenafullaccess-managed-policy)`AmazonAthenaFullAccess`**ポリシーを使用すると**、S3の権限不足（恐らく`s3:GetObject`か`s3:PutObject`権限が対象バケットに紐付けられていない事が原因）でPython SDKの`get_query_execution()`メソッドが動きませんでした）


#### Redshift Spectrumで必要なアクセス権限

コンソール操作用とRedshiftクラスタへのアタッチ用の2種類のポリシーが必要となる事にご注意ください。詳細は以下を参照ください。

https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#前準備

#### 作成したポリシーの適用方法

作成したポリシーをデータレイク機能の使用元に適用するためには、使用元の種類に応じて以下の方法を取ります

- **ローカルからの使用時: ポリシーをユーザーに付与したのち、このユーザーから生成したアクセスキーをCLIに登録**

- **EC2やFargate等のAmazonリソースからの使用時: ポリシーをロールに付与したのち、このロールをEC2等にアタッチ**

実際の適用方法は、後述の[S3 Select](https://qiita.com/c60evaporator/items/a926097d7275f07fef03#アクセス権限の付与)、[Athena](https://qiita.com/c60evaporator/items/2695f0ceeccbbda1bac9#アクセス権限の付与)、[Redshift Spectrum](https://qiita.com/c60evaporator/items/31d89b3b68d96708a379#前準備)、[EMR]()それぞれの使い方記事、または以下のIAMの記事を参照ください。

https://qiita.com/c60evaporator/items/0121399880625cc1de51#aws内サービスへの権限付与

## S3 Selectの使用法

S3 Selectの、コンソールおよびSDKからの実際の使用法は、**以下の記事にまとめました**。

https://qiita.com/c60evaporator/items/a926097d7275f07fef03

## Athenaの使用法

Athenaでも、S3 Slectと同様にコンソール、SDKを利用してS3内のデータをクエリする事ができます。

S3 Selectと比べて一般的なデータベース（RDB）に近い操作となり、具体的には以下の手順でクエリを実行します

- ステップ1: データベースの作成
- ステップ2: テーブルの作成
- ステップ3: クエリの実行

実際のAthenaの使用法は、**以下の記事にまとめました**。

https://qiita.com/c60evaporator/items/2695f0ceeccbbda1bac9

## Redshift Spectrumの使用法

実際のRedshift Spectrumの使用法は、**以下の記事にまとめました**。

https://qiita.com/c60evaporator/items/31d89b3b68d96708a379

## EMRの使用法

具体例としてS3 + EMR + PySparkでの実装法を**以下の記事で紹介**します。

[記事作成中]()