aws lambda with java/scala #渋谷java 第十二回
TRANSCRIPT
AWS Lambda with Java/Scala
@hajimeni #渋谷Java 第十二回
アジェンダ
• 自己紹介
• AWS Lambdaについて
• JavaとかScalaでやってみた
• 料金とか
自己紹介• 西山はじめ( twitter、github: @hajimeni )
• 株式会社ビズリーチ
• スタンバイ事業部。C側サイト、内部API、社内管理ツール開発 etc…
• 言語
• Java, C#, JavaScript(CoffeeScript), Scala, (python) etc…
• やってること(やってきたこと)
• 基本的にWebアプリケーション開発
• RDB(Oracle, MySQL)の運用などに携わることが多い。
• インフラまわりもちょっと
• AWS全般、Solr、MongoDB、Cassandra、memcached, Redis
• 最近は hubot とか pythonとかでScriptつくることも。
Amazon Aurora• 先日リリース(2015/07/28)
• MySQL互換のRDSサービス
• MySQLのJDBCドライバで接続可能
• ダウンタイム0でマイグレーション
• ストレージの自動拡張(64TBまで)
• MySQL5.6の5倍速い(Amazon調べ)
• 東京リージョン(ap-northeast-1)にはまだない
• 今日はAWS AuroraLambdaの話です。
AWS Lambda とは• AWSのイベント発生をトリガーにして、あらかじめ登録しておいたコードを実行できるサービス
• Event Sources
• S3
• Kinesis
• DynamoDB Streams(Preview)
• Dynamo
• Cognito(eu-west1, us-east1 only)
• 使用可能なコード
• Java8
• Node.js
•
S3
DynamoStreams
Kinesis
SNS
Cognito
Amazon Echo Alexa Skills kit
イメージ
Javaで• Eclipse Plugin
• AWS Toolkitを使うと楽
http://docs.aws.amazon.com/ja_jp/AWSToolkitEclipse/latest/GettingStartedGuide/Welcome.html
コード例package com.github.hajimeni.lambda.java;
import java.util.HashMap;
import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.S3Event;
public class LambdaFunctionHandler implements RequestHandler<S3Event, Object> {
@Override public Object handleRequest(S3Event input, Context context) { context.getLogger().log("Input: " + input);
HashMap<String, String> map = new HashMap<>(); map.put("result", "OK"); return map; }
}
戻り値は自由に定義できる。 API Gatewayと組み合わせるなら
JSON。 MapやListはJSONに変換してくれる
AWS Lambdaに登録• Projectを右クリック
CloudFrontのLog書き込み、S3へのアクセス用のRole
が必要
ここのMemoryサイズで100msあたりの金額が違う。
登録結果
• 24MB・・・
• CodeSize = jar のサイズ
• 10MB超えるとS3にアップロードして設定
テスト実行
テスト結果
戻り値
実行時間と課金対象となった時間ログ出力
Event source
ObjectCreated (Post, Put, Copy, Upload)
Object Removed (Delete)
※多分昨日か一昨日に追加
実際にS3にPUT• LogはCloudWatchのLogs
• /aws/lambda/${function_name}
• 時間や実際に使用したMaxMemory使用量が表示される
Scalaで• sbt でプロジェクト作成
• build.sbt に追記
• project/plugins.sbtに sbt-assembly 追加
libraryDependencies ++= Seq( "com.amazonaws" % "aws-lambda-java-core" % "1.0.0", "com.amazonaws" % "aws-lambda-java-events" % "1.0.0" )
// sbt 0.13.6+ addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.13.0")
// ~ sbt 0.13.6 addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
コードのサンプルpackage com.example
import com.amazonaws.services.lambda.runtime.events.S3Event import scala.collection.JavaConverters._
/** * Created by nishiyama on 2015/07/26. */ class S3PutLogger {
def logS3Meta(event: S3Event): java.util.List[String] = { val keyNames = event.getRecords.asScala.map{ record => record.getS3.getObject.getKey } keyNames.foreach(println) keyNames.asJava } }
戻り値の型はJavaにしたほうがAPIGatewayを使いやすい
標準出力はCloudWatchで見れる
登録
• one-jarを生成
• 1ファイル(1jar)しかLambdaには設定出来ない
• 10MBまでなら直接アップロード可能。
• それ以上はS3においてから設定する
• AWS Consoleで設定
• sbt pluginが欲しいかも。(% sbt publish-lambda みたいな)
% sbt assembly
並列で処理• 複数のファイルを同時にS3にアップロード
• (試しに10個)
• 1個処理したログ
• 何個か同時に処理したログ
• S3のEvent通知
• →Pushモデルなので、順番は保証されない
• →DynamoDB Streams, Kinesis, SNSはPullモデル。順番を保証。
• http://docs.aws.amazon.com/lambda/latest/dg/intro-invocation-modes.html
実行時間とか
•
1回目 連続した2回め以降
Java8 100ms ~ 数百ms 数ms
Node.js 数ms ~数十ms 数ms
※HelloWorldのログ出力のみ ※それぞれ10回実行した後、再登録しなおして計測
1回目のブレ幅は大きいので参考情報。
実行環境[ { model: 'Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz', speed: 2800, times: { user: 77900, nice: 0, sys: 43500, idle: 95220900, irq: 0 } }, { model: 'Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz', speed: 2800, times: { user: 81800, nice: 0, sys: 46000, idle: 95543700, irq: 0 } } ]
OS:3.14.44-32.39.amzn1.x86_64 Memory: 3768.2890625 MB HostName: ip-10-0-x-x
CPUとMemoryから c3.large インスタンスで実行されている
Memory設定変えても同じHostの場合がある →ECS?
課金ポイント• リクエスト数
• 毎月100万件まで無料、その後$0.2/100万件
• 実行時間(512MBの場合)
• 800,000秒まで無料( -> 9.25日 )
• その後、$0.000000834/100ms
• → $0.03/1h
• 1プロセスで1ヶ月ずっと動かしっぱなし -> 約$15
各メモリ毎料金メモリ (MB) 1 か月の無料 100 ミリ秒単位の 1 秒 1 時間 無料枠 時間128 3,200,000 0.000000208 0.00000208 0.007488 889192 2,133,333 0.000000313 0.00000313 0.011268 592256 1,600,000 0.000000417 0.00000417 0.015012 444320 1,280,000 0.000000521 0.00000521 0.018756 255384 1,066,667 0.000000625 0.00000625 0.0225 296448 914,286 0.000000729 0.00000729 0.026244 254512 800,000 0.000000834 0.00000834 0.030024 222576 711,111 0.000000938 0.00000938 0.033768 198640 640,000 0.000001042 0.00001042 0.037512 178704 581,818 0.000001146 0.00001146 0.041256 162768 533,333 0.000001250 0.000012500 0.045000000 148832 492,308 0.000001354 0.00001354 0.048744 137896 457,143 0.000001459 0.00001459 0.052524 127960 426,667 0.000001563 0.00001563 0.056268 1191024 400,000 0.000001667 0.00001667 0.060012 1111088 376,471 0.000001771 0.00001771 0.063756 1051152 334,641 0.000001875 0.00001875 0.0675 931216 281,803 0.000001980 0.000019800 0.071280000 781280 225,442 0.000002084 0.00002084 0.075024 631344 171,765 0.000002188 0.00002188 0.078768 481408 124,920 0.000002292 0.00002292 0.082512 351472 86,901 0.000002396 0.00002396 0.086256 241536 57,934 0.000002501 0.00002501 0.090036 16
追加でかかる料金
• EC2からのデータ転送
• S3のリクエスト、データ転送、ファイルサイズ
• DynamoDBのストレージ、スループット、データ転送
EC2との単純比較• 24h/1ヶ月稼働し続けていた場合
1hあたり 1ヶ月EC2 c3.xlarge $0.105 $75
EC2 t2.micro $0.013 $9.36
Lambda 128MB x 1 $0.007 $0(※)
Lambda 128MB x 2 $0.014 $4.1
Lambda 1536MB x 1 $0.09 $64
※本当に計算するときは、 Request数 x 1Requestあたりの処理時間
• 例: 月間500万 Request。
• 1リクエストあたりの処理時間 = 500ms
• 1,024MB の Lambda(無料枠40万秒)
• (5,000,000 * 0.5 - 400,000) * 10 * 0.000001667 = $35
制限事項• 常駐処理をするにはむいていない
• タイムアウトは 60s までなので長い処理はできない
• →非同期にしても処理時間が60sまで
• VPC内のEC2やRDSなどを参照にするにはPublicからのアクセスを許可する必要がある。(現時点では制限と書いてあるからもしかしたら・・・)
• Node.jsの方が気軽
• 地味にImageMagicだけNative Libraryが入ってる
• http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/current-supported-versions.html
まとめ• 割りと気軽に使える
• ファイルサイズは基本大きくなる(Java8の場合)
• 初回の実行時間はおそい(場合もある)
• 金額計算は、実行時間依存。
• 今日はできていないけど、API GateWayのバックエンドにもなる。
API GatewayREST API
(http://example.com/${stage}/${api_name})
参考• Writing AWS Lambda Functions in Scala
• https://aws.amazon.com/jp/blogs/compute/writing-aws-lambda-functions-in-scala/
• Lambda Function が Java で書けるようになりました!
• http://dev.classmethod.jp/cloud/aws/lambda-function-in-java/