web-dev-qa-db-ja.com

AWS Kinesis firehoseからAWS S3に寄木細工を書く

寄木細工としてフォーマットされたキネシスファイアホースからs3にデータを取り込みたいです。これまでのところ、EMRを作成することを意味する解決策を見つけましたが、受け取ったjsonをfirehoseから直接寄木細工として保存したり、Lambda関数を使用したりするような安価で高速なものを探しています。

どうもありがとう、ハビ。

23
bracana

良いニュース、この機能は本日リリースされました!

Amazon Kinesis Data Firehoseは、入力データの形式をJSONからApache ParquetまたはApache ORCに変換してから、Amazon S3にデータを保存できます。寄木細工とORCは、スペースを節約し、より高速なクエリを可能にする円柱状のデータ形式です

有効にするには、Firehoseストリームに移動してクリックします Edit。次のスクリーンショットのように、レコード形式の変換セクションが表示されます。

enter image description here

詳細については、ドキュメントを参照してください: https://docs.aws.Amazon.com/firehose/latest/dev/record-format-conversion.html

15
Vlad Holubiev

AWSサポートサービスと数百の異なる実装を扱った後、私が達成したことを説明したいと思います。

最後に、Kinesis Firehoseによって生成されたすべてのファイルを処理し、ペイロードに従ってイベントを分類し、結果をS3のParquetファイルに保存するLambda関数を作成しました。

それをするのはとても簡単ではありません:

  1. まず、必要なすべてのライブラリ(私の場合はPandas、NumPy、Fastparquetなど)を含むPython仮想envを作成する必要があります。結果ファイルとして(すべてのライブラリとmy Lambda関数は重いため、EC2インスタンスを起動する必要があります(無料利用枠に含まれているものを使用しました)。仮想envを作成するには、次の手順に従います。

    • EC2でログイン
    • Lambda(またはその他の名前)というフォルダーを作成します
    • Sudo yum -y update
    • Sudo yum -y upgrade
    • Sudo yum -y groupinstall「開発ツール」
    • Sudo yum -y install blas
    • Sudo yum -y install lapack
    • Sudo yum -y install atlas-sse3-devel
    • Sudo yum install python27-devel python27-pip gcc
    • Virtualenv env
    • ソースenv/bin/activate
    • pip install boto3
    • pip install fastparquet
    • pIPインストールパンダ
    • pip install thriftpy
    • pip install s3fs
    • pip install(その他の必要なライブラリ)
    • 〜/ lambda/env/lib */python2.7/site-packages/-name "* .so"を見つけます| xargsストリップ
    • pushd env/lib/python2.7/site-packages /
    • Zip -r -9 -q〜/ lambda.Zip *
    • ポッド
    • pushd env/lib64/python2.7/site-packages /
    • Zip -r -9 -q〜/ lambda.Zip *
    • ポッド
  2. Lambda_functionを適切に作成します。

    import json
    import boto3
    import datetime as dt
    import urllib
    import zlib
    import s3fs
    from fastparquet import write
    import pandas as pd
    import numpy as np
    import time
    
    def _send_to_s3_parquet(df):
        s3_fs = s3fs.S3FileSystem()
        s3_fs_open = s3_fs.open
        # FIXME add something else to the key or it will overwrite the file 
        key = 'mybeautifullfile.parquet.gzip'
        # Include partitions! key1 and key2
        write( 'ExampleS3Bucket'+ '/key1=value/key2=othervalue/' + key, df,
                compression='GZIP',open_with=s3_fs_open)            
    
    def lambda_handler(event, context):
        # Get the object from the event and show its content type
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key'])
        try:
            s3 = boto3.client('s3')
            response = s3.get_object(Bucket=bucket, Key=key)
            data = response['Body'].read()
            decoded = data.decode('utf-8')
            lines = decoded.split('\n')
            # Do anything you like with the dataframe (Here what I do is to classify them 
            # and write to different folders in S3 according to the values of
            # the columns that I want
            df = pd.DataFrame(lines)
            _send_to_s3_parquet(df)
        except Exception as e:
            print('Error getting object {} from bucket {}.'.format(key, bucket))
            raise e
    
  3. Lambda関数をlambda.Zipにコピーして、lambda_functionをデプロイします。

    • EC2インスタンスに戻り、目的のラムダ関数をZipに追加します。Zip -9 lambda.Zip lambda_function.py(lambda_function.pyはステップ2で生成されたファイルです)
    • 生成されたZipファイルをS3にコピーします。S3を介してそれを行うと非常に重いため、展開するのは大変です。 aws s3 cp lambda.Zip s3:// support-bucket/lambda_packages /
    • ラムダ関数をデプロイします:aws lambda update-function-code --function-name --s3-bucket support-bucket --s3-key lambda_packages/lambda.Zip
  4. たとえば、S3で新しいファイルが作成されるたびに、またはラムダ関数をFirehoseに関連付けることもできます。 (「ラムダ」の制限がFirehoseの制限より低いため、このオプションを選択しませんでした。128Mbまたは15分ごとにファイルを書き込むようにFirehoseを構成できますが、このラムダ関数をFirehoseに関連付けると、ラムダ関数が実行されます私の場合、ラムダ関数が起動されるたびに少なくとも10個のファイルを生成するため、3分または5MBごとに、小さな寄せ木細工のファイルを大量に生成するという問題がありました。

20
bracana

Amazon Kinesis Firehoseはストリーミングレコードを受信し、Amazon S3(またはAmazon RedshiftまたはAmazon Elasticsearch Service)に保存できます。

各レコードは最大1000KBです。

Kinesis flow

ただし、レコードはテキストファイルに追加され、時間またはサイズに基づいてバッチ処理されます。従来、レコードはJSON形式です。

寄木細工のファイルを送信できませんになります。これは、このファイル形式に準拠しないためです。

Lambdaデータ変換関数をトリガーすることは可能ですが、これは寄木細工のファイルを出力することもできません。

実際、寄木細工のファイルの性質を考えると、それらを作成できるとは考えられません一度に1レコード。列単位のストレージ形式であるため、レコードごとにデータを追加するのではなく、バッチで作成する必要があると思います。

一番下の行:いいえ。

9
John Rotenstein