A Zero Administration AWS Lambda Based Amazon Redshift Database Loader を HTTP Proxy 経由で利用する

  • 0
    Like
  • 0
    Comment

    はじめに

    S3上のログファイルを、逐次Redhisftに取り込んでいきたいと思って調べてみると、AWS謹製の A Zero Administration AWS Lambda Based Amazon Redshift Database Loadera Based Amazon Redshift Database Loader (名前長い。以降、Redshift Loaderとする。) が良さそうです。

    仕組みを調べてみると、RedshiftやS3、LambdaはVPC Endpointによってプライベートネットワークで接続し、設定情報や対象ファイルの管理に使うDynamoDBはNATゲートウェイ経由でパブリックネットワーク経由の接続が前提になっていました。

    使おうとしていた環境のVPCでは、NATゲートウェイを使用せず、HTTP ProxyによってパブリックIPの無いインスタンスでのインターネット向け通信を実現していたため、HTTP Proxy対応を行ったソースを使っての導入手順をまとめます。

    HTTP Proxy対応については、PR を出しています。この記事を書いている段階ではまだ取り込まれていません。

    Redshift Loaderで出来ること

    • S3にログが書き込まれたイベントをきっかけに、Redshiftへロードするファイルリストを管理
    • 指定したバッファサイズ、件数又は時間ベースの閾値をトリガーにしてRedshiftへのロードを実行
    • ロード実行は、1ファイル1回を保証
    • 成功・失敗時のSNS通知
    • コマンドラインからの、ロード処理のバッチ進行状況の確認、再実行等
    • S3でのイベントトリガーは複数設定でき、1つのLambdaファンクションがイベントに応じてスケールして処理する

    手順概要

    • S3バケットの作成とログのアップロード、VPCエンドポイントの設定
    • Redshiftインスタンス・テーブル、DBユーザーの作成
    • 設定・運用ツール実行のためのNode.js環境の構築
    • Lambdaファンクションのデプロイ
    • Redshift Loaderの設定
    • ログが取り込まれていることの確認

    S3バケットの作成とログのアップロード、VPCエンドポイントの設定

    本記事を書いている際には、ApacheのエラーログのアップロードをFluentdで実施して試しています。特に注意点も無いので、説明は省略します。

    • Redshiftインスタンス、Lambdaファンクションと同じリージョンで作成
    • アップロードは fluentd(td-agent) 辺りで実施
    • ログの保管用 と Redshift LoaderがCOPYコマンド(Redshift)で指定するためのマニフェスト保管用の計2バケットが最低限必要

    Redshiftインスタンス・テーブル、DBユーザーの作成

    インスタンスの作成

    以下の設定項目に注意する。

    • S3バケット、Lambdaファンクションと同じリージョンで作成
    • パブリックアクセス可能(Publicly accessible) : No
    • 拡張された VPC のルーティング(Enhanced VPC Routing) : Yes
    • IAMロール(Available roles): 連携するS3バケットに対して、s3:GetObject 及び s3:ListBucket を許可しておく

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "s3:GetObject",
                      "s3:ListBucket"
                  ],
                  "Resource": [
                      "arn:aws:s3:::your-s3-bucket",
                      "arn:aws:s3:::your-s3-bucket/*"
                  ]
              }
      }
      
      • この時点で COPY コマンドで、S3からデータがロードできることを確認しておく

    参照ドキュメント

    テーブルの作成

    Apacheエラーログを、fluentdのin_tailオプションによって、JSONにパースした場合の一例。

    create table if not exists apache_errors(
      time TIMESTAMPTZ,
      hostname VARCHAR(256),
      domain VARCHAR(256),
      message VARCHAR(8192),
      client VARCHAR(21),
      pid VARCHAR(5),
      level VARCHAR(32)
    ) 
    DISTKEY(hostname)
    SORTKEY(time);
    

    DBユーザーの作成

    前述のテーブル専用のユーザーを作る場合の一例。

    create user load_apache_errors password 'パスワードに置き換え';
    grant all on table apache_errors to load_apache_errors;
    

    設定・運用ツール実行のためのNode.js環境の構築

    設定・運用ツールは、Node.jsの0.10又は0.12でのみ確認されているとあるため、ndenv等で環境を用意します。

    ndenv を導入した前提で、次のように利用するバージョンを指定します。

    ndenv install v0.12.18
    
    git clone https://github.com/tkimura/aws-lambda-redshift-loader
    cd aws-lambda-redshift-loader
    
    ndenv local v0.12.18
    
    npm install
    
    • ndenv でインストールしているバージョンは、本記事記載時点の0.12系最新
    • PR が 取り込まれていないので、リポジトリは fork して修正したバージョンです

    Lambdaファンクションのデプロイ

    アップロード用のzipを作成

    cd aws-lambda-redshift-loader
    git checkout add-proxy-support
    ./build.sh
    
    • 前述手順でcloneして、ndenv local で設定済みであることを想定
    • ./dist/ 以下に zip ファイルが作成される

    出来上がったzipファイルをアップロード

    IAMロールの設定

    • 前述ドキュメントに記載の設定例を指定
    • 作成したロールに、AWSLambdaVPCAccessExecutionRole ポリシーを追加する (VPC利用のため)

    Proxyの設定

    • Lambdaファンクションの環境変数に設定を追加

    Redshift Loaderの設定

    cd aws-lambda-redshift-loader
    git checkout add-proxy-support
    vi config.json # このファイルに設定を書いておく
    node setup-file.js ./config.hoge.json
    

    設定及び運用コマンドの実行環境向けのIAMポリシー

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "dynamodb:CreateTable",
                    "dynamodb:DeleteItem",
                    "dynamodb:DeleteTable",
                    "dynamodb:GetItem",
                    "dynamodb:PutItem",
                    "dynamodb:Query",
                    "dynamodb:UpdateItem"
                ],
                "Resource": [
                    "*"
                ]
            },
            {
                "Effect": "Allow",
                "Action": [
                    "kms:CreateAlias",
                    "kms:CreateKey",
                    "kms:Decrypt",
                    "kms:DescribeKey",
                    "kms:Encrypt"
                ],
                "Resource": [
                    "*"
                ]
            }
        ]
    }
    

    ログが取り込まれていることの確認

    • CloudWatch Logs で Lambdaファンクションが実行されていることを確認
      • Proxy設定が正しくないと、タイムアウト時間いっぱいまで動いて失敗する
    • Redshiftインスタンスに直接繋いで確認する

      • PGTZ変数でタイムゾーンを指定しておくと時間がわかりやすい
      • タイムゾーン付き(TIMESTAMPTZ)でテーブルを作っておくと、PGTZで指定したタイムゾーンに合わせて表示される
      PGTZ="Asia/Tokyo" psql -U ユーザー名 -h Redshiftインスタンスのエンドポイント logs
      

    費用感

    Redshiftへのロード頻度を上げたり、並列数(アクセスログをドメイン別に数十とか)を上げていくと、Redshift・S3とは別に、DynamoDBやLambdaの費用だけで数百ドルを超える費用が見込まれるたりもするので、頻度や並列数に合わせて要試算。

    • DynamoDB
      • Read/Write共にキャパシティを増やす必要あり
      • メトリクスを観察しながら増やしていくと、マネジメントコンソール上でコスト感が確認出来る
    • Lambda
      • 毎分でサーバ台数が多く、並列数も多いと、実行時間・実行回数ともに増えていく
      • 試算ツールがあるので、しばらく稼働させた結果から月間の見込み数値を入れると計算できる
    • Redshift
      • 並列数、実行回数が伸びてくると、dc1.large × 1ノードでは不足してくる
        • これもCloudWatch LogsやSNSへのアラートを見ながら増やす必要あり

    参考ドキュメント