AppFlowのデータ処理料金について確認してみる

この記事は[BeeX Advent Calendar 2022](https://qiita.com/advent-calendar/2022/beex)の14日目の記事です。
またもや投稿遅刻しました(投稿日12/16)

# はじめに
AppFlowでは、フローの実行料金とAppFlowが処理したデータ処理料金の2つが課金対象となっており、東京リージョンでは以下の料金が発生します。

* フロー実行料金：$0.001
* AWS でホストされている宛先のフローのデータ処理料金：$0.09/GB
* 宛先が AWS PrivateLink (AWS または外部でホスト) と統合されているフローのデータ処理料金：$0.09/GB
* 宛先が AWS でホストされておらず、かつ AWS PrivateLink と統合されていないフローのデータ処理料金：$0.09/GB(~1GB)、$0.124/GB(1GB~)

このうち、フロー実行料金はAppFlowフローの実行回数に対する課金なのでわかりやすいのですが、データ処理料金については取得元のデータサイズで計算できるものではないのでランニングコストの試算がざっくりとしか出すことができません。

[こちらのドキュメントをみると](https://aws.amazon.com/jp/appflow/pricing/)「料金は、データ処理 (スキーママッピング、フィールド検証、フィルタリング、マスキングフィールド、およびフィールド変換) に対して発生します」と記載があるので、ソースのデータサイズに依存するというよりはフィールド数に依存して処理サイズが増加しそうですが、ドキュメントには具体的に明記まではされていませんでした。

一応AWSサポートに問い合わせてみたところ、AppFlowコンソールの以下の実行履歴に記載されている転送サイズが上記のデータ処理料金の対象になると回答があったので、今回はこれをベースにいくつかパターンを準備して処理サイズがどう増加するかどうか検証をしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/91cbc170-7a1a-ca71-44eb-7c9cb6e31c74.png)


# 検証内容
## 条件
ソース元のデータによって変わってくる可能性がありますが、今回は一番わかりやすいS3からS3への連携で試してみます。
ソースデータはフィールド数、レコード数でいくつかパターンを準備していて、データサイズは1GB、10GBなど揃えられなかったので、一旦作成したCSVファイルのサイズを以下のパターン表にそのまま載せています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/5bd45498-e1c2-87d1-3251-f33152d77570.png)

AppFlowフローを分割して作成するため、CSVファイルの格納先もフォルダ分けしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/40aa9e6a-6549-f22c-ffe2-5b8c4707063a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/9dcd3a27-75a0-1d35-8b88-f527b1322132.png)

AppFlow側の設定はFrom/ToはS3の別バケットを指定し、フィールドはフルマッピング、フィルタリングやマスキングは未設定とします。
書き込みデータの形式はCSV、ファイル名にタイムスタンプを追加する設定とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/32b075ce-5068-061b-792a-801b9f17a31b.png)

また、パーティションは作成せず、全てのレコードを1つのファイルに集約する設定にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/b2d39ddc-abaa-169f-f30e-35374db5d7fc.png)

## この記事の検証で分かったこと(S3からS3へのデータ連携の場合)
* データ処理対象となるのはAppFlow上でマッピングされたフィールドのみ(マッピングされてなければ対象外)
* 一度フロー実行してフィールド数・レコード数・転送サイズが分かればそれを元にしたある程度の転送サイズの予測は可能
* フィールド名自体のサイズが転送サイズに大きく影響してそう(詳細な計測はできていない)

## 検証結果
全部見ると長いので、サッと見たい方はサマリを見てください。

### サマリ
まず全体としてみたときに、フィールド数が同じでレコード数だけが増えた場合は、レコード数の増加にほぼ比例してデータ処理サイズも増加するようになっていました。
出力データサイズは※に記載の変換が入っているので若干ソースのCSVよりも増えていますが、レコード数の増加に合わせて出力データサイズもほぼ比例してるように見えます。
APｐFlow処理時間は今回検証したフィールド数やレコード数では然程大きな差は出てませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/be67bfee-e210-a70a-63f0-ff525947ef90.png)

また、レコード数が同じでフィールド数が増えた場合も、レコードの増加と同じくフィールド数の増加にほぼ比例してデータ処理サイズが増加していました。
ただ、今回はCSVファイルをソースとしていたので、フィールドのデータ型も文字列型で認識されていましたが、これがSalesforceなどになった場合は文字列型以外も含まれるため、その場合はほぼ比例するとは言えない可能性もあります。
これはちょっと検証パターンが良くなかったかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/a7473e8b-4a54-9c79-1276-277125252f46.png)

※出力サイズが微妙に増えていますが、これは出力されたCSVファイルには""が自動的に付いているので、その分だけサイズが増えたのだと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/dcb41ebb-d98d-865f-95a1-534c64ec56fa.png)

### フィールド数10、レコード数10の場合
(S3からS3に連携する場合はフィールド名の行も1レコードと認識されるのを失念していました。。)
フローを実行すると転送サイズは1.572KB、転送レコードは11レコード、処理時間は6.8秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/e21404c2-e0b5-783e-eb49-1e6e5c2ab72b.png)

### フィールド数10、レコード数100の場合
フローを実行すると転送サイズは15.262KB、転送レコードは101レコード、処理時間は6.61秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/400b4023-12cd-9025-632b-76ff15f93d17.png)

### フィールド数10、レコード数1000の場合
フローを実行すると転送サイズは161.072 KB、転送レコードは1001レコード、処理時間は6.32秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/55452a9d-294a-c450-c621-b61d6c2cac8b.png)

### フィールド数100、レコード数10の場合
フローを実行すると転送サイズは16.523 KB、転送レコードは11レコード、処理時間は5.97秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/24e5fc8b-6dbb-6003-e46c-c95049155eb5.png)

### フィールド数100、レコード数100の場合
フローを実行すると転送サイズは159.993 KB、転送レコードは101レコード、処理時間は6.34秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/0c1b287f-1680-8646-9948-addae8e9a175.png)

### フィールド数100、レコード数1000の場合
フローを実行すると転送サイズは	1.683793 MB、転送レコードは1001レコード、処理時間は6.51秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/87033907-f824-aebe-d3e9-598b6fcde6f8.png)

### フィールド数1000、レコード数10の場合
フローを実行すると転送サイズは175.834 KB、転送レコードは11レコード、処理時間は8.33秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/de5e206b-6c61-ce56-7462-86804e87132f.png)

### フィールド数1000、レコード数100の場合
フローを実行すると転送サイズは1.697294 MB、転送レコードは1001レコード、処理時間は5.88秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/3e060b12-2da5-ae2c-5d20-abcc51f52166.png)

### フィールド数1000、レコード数1000の場合
フローを実行すると転送サイズは17.802894 MB、転送レコードは1001レコード、処理時間は11.48秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/b4400a32-34a6-40ec-ce3f-a48c2c91b9b0.png)

## 追加検証(フィールドとレコードを減らしてみる)
[ドキュメント](https://aws.amazon.com/jp/appflow/pricing/)の記載から課金対象のデータ処理は以下の5つだと思いますが、フィルタリングとマスキングは設定していないことから実際に処理されたのは3つではないかと思います。
しかし、ソースデータサイズとAppFlow処理サイズを比べてみると約5倍になっていることから、少なくとも3回以上ソースデータを処理したか、ソースデータ以上のデータを扱う処理が裏側で行われた可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/f529873f-0ddf-2411-3338-f6590db33c5b.png)

* スキーママッピング →　恐らく処理されている
* フィールド検証 →　恐らく処理されている
* フィルタリング →　未設定のため恐らく未処理
* マスキングフィールド →　未設定のため恐らく未処理
* フィールド変換 →　恐らく処理されている

処理名からして、以下のAppFlow上でマッピングされたフィールドの数によって処理データサイズが変動するようになっている気がします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/00e7935e-6d59-fa4a-2aef-3ac109d4d71c.png)

試しにS3上のソースデータは変更せずにAppFlow上のマッピングフィールドを1つ減らして実行したところ、転送サイズも減ったのでAppFlow内で処理する前にマッピングされていないフィールドは処理対象から除外されているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/6ba3d591-8af3-6ec9-601b-6031380921ee.png)

他にも1フィールドずつ減らしていくとどう変化していくかみたところ、1フィールド減らすごとに155B減っていき、10フィールド→1フィールドになった時は10フィールドの10分の1程度の転送サイズになっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/0099f09a-2751-afd2-737d-072a04a1b8df.png)

更にレコードを11→1に減らして実行してみたところ、転送サイズも10分の1程度の転送サイズになっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/2605a45d-22b8-8011-2c0d-7cc96f5ae2b3.png)

以上のことから、データ処理対象となるのはAppFlow上でマッピングされたフィールドのみで、一度フロー実行してフィールド数・レコード数・転送サイズが分かればある程度の転送サイズの予測は可能だと思われます。(一度実行しないといけないというのがネックですが)

## 追加検証(フィールド名を操作してみる)
1つ考えたのは、データ処理の対象としているのはフィールド周りの検証や変換が主になっているので、フィールド名を変更すればフィールドやレコードを減らさなくても転送サイズを減らせるんじゃないか、と思いました。
そこで以下のようにフィールド名を減らして再度実行してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/f35eff84-a831-75aa-65d5-bbe2afdde097.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/80913a56-6c87-34ef-c435-10625d26f982.png)

結果としては想定通りのもので、以下キャプチャの下がフィールド名修正前、上が修正後で、転送サイズが330KBも減っていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/7519c390-58d2-8676-0359-1b57ee9ca60a.png)

今度はフィールド1つ、レコード1つの7Bのファイルを作成して実行してみます。尚、7Bはフィールド名5B、改行(LF)1B、レコード1Bの計7Bになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/cbef1f2d-7d0a-39af-8a65-774c053acaf5.png)

転送サイズが13Bになりました。これだけを見るのであれば、
スキーママッピングとフィールド変換は確実にされていると思うので5B×2=10B
フィールド検証と変換はレコードに対しても行われていると思うので1B×2=2B
改行(LF)1Bは変換時に処理されていると思うので1B×1=1B
合計10B＋2B＋1B＝13B、みたいに想定ができるのでしょうけど、確証までは得られないのと他パターンを試すと当てはまらない気がします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/2f54047c-5fc0-d219-71f4-664ebca6ab95.png)

実際、フィールド名を5文字から10文字に増やして実行してみたところ、上記理論であれば20Bは超えてないとおかしいですが18Bでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440403/cc02b91d-2787-f265-cb5c-5d97664d531d.png)

# おわりに
うーん、フィールド名自体のサイズが転送サイズに大きく影響してそうだ、ということはわかりましたが、だからといってフィールド名から転送サイズが推測できるものではなさそうなので、今回はこれぐらいで検証終わります。
AppFlowはネットワークやロジック周りのドキュメントや説明しているものが他のAWSサービスに比べるとかなり少ないので、AppFlow DeepDiveとかあって裏側の仕組みを説明される機会があれば是非聞きに行きたいと思います。

確認した結果よくわからなかったというのがもやもやしますが、また何かわかったことがあれば記事にしたいと思います。
この記事がどなたかの参考になっていれば幸いです。