計算量の必要なロジックを AWS に計算させてはどうかと思った。

AWS Lambda を使えば、サーバを立ち上げなくても、ロジックの一部を切り出して実行させることができそうだ。HTTP で URL にパラメータを付けて GET すれば計算結果が返ってくる、といったことをやってみようと思う。

lamba 関数と API の作成

以下の手順で作成する。

  1. AWS Lambda のダッシュボードから関数を作成を選択。
  2. 設計図には、ブランク関数を選ぶ。
  3. トリガーに、API Gateway を選択。(HTTPで実行させたいため。)テスト用なので、セキュリティには、オープンを設定。
    関数名を入力。
  4. ランタイムは、とりあえず、python 2.7 を選択。
  5. Lambda 関数のコードには以下のように記述。
def lambda_handler(event, context):
    # TODO implement
    return {"statusCode": 200, "body": "hello"}

もし、json データを返したいのであれば、

"body": '{"resp": "hello"}'

などのようにする必要がある。

あとは適当に入力して、関数の作成ボタンを押す。関数の作成に成功したら、トリガーに表示されている URL をクリックしてみよう。結果が表示されるはずだ。

トラブルシュートの方法

私は、最初、lambda 関数の作成時、デフォルトのコードで実行して少しハマってしまった。URL をクリックしても internal server error が返っていた。

以下のようにするとログが表示されるのでどこまで実行されているかわかる。ここに気づくのに時間がかかった。

  1. Amazon API Gateway サービス > API > リソース > 関数名 を選択
  2. メソッド名を選択(または ANY)
  3. テストを押す
  4. メソッド GET を選択
  5. テストボタンを押す

ログの最後のほうに、

Thu Apr 06 20:05:34 UTC 2017 : Execution failed due to configuration error: Malformed Lambda proxy response

とある。

lambda が返すべき書式が決まっているらしい。

{
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

のような応答を返す必要がある。

ドキュメントを参照してほしい。

パラメータを渡して結果を得る

さて、query parameter でパラメータを渡して、結果を返してみたい。何をやろうとしているかバレバレであるが、lambda 関数を以下のように変えてみる。

import json

def lambda_handler(event, context):
    qs = event['queryStringParameters']
    result = {"result": qs['hash'] + qs['nonce']}
    # TODO implement
    return {"statusCode": 200, "body": json.dumps(result)}

URL?hash=1234&nonce=1234 などとすると、hashとnanceを結合した文字列が返る。

プログラミングモデル
ハンドラーなどが参考になろう。

print すれば、cloudwatch のログに出力されるし、API Gateway からテストを実行すれば、実行状況も追うことができるだろう。

あとは、自由にロジックを入れてみよう。面白いサービスがあるものです。

追記:速度について

sha256 を二回計算させるロジックを AWS に置いてみたところ、10万回ループで、約6秒(=16k Hash/s)。threading でマルチスレッドにしても、計算時間はスレッド数に比例する感じ。(thread にしても意味がない)

bitcoin の採掘に ASIC が必要というのがよくわかる。