Mais conteúdo relacionado Semelhante a Smart Tennis Lesson Serverless Design (20) Smart Tennis Lesson Serverless Design2. 自己紹介 : TAKEHARA Ryuji
l SONY Network Communications
CloudDevOps Div
l Sports & IoT team leader
l My best Serverless services
l Lambda & S3
l My best sports
l KENDO (3 dan desu.)
l Contact
l Ryuji.TAKEHARA@sony.com
l @kozyupapa
I love Sports,
I like IoT.
四街道(千葉県)に移住においでよ!
2
4. Smart Tennis Lesson(STL) 2017 3月より全国導入
https://victorysportsnews.com/articles/4515/original
* ソニー株式会社事業開発プラットフォーム新規事業部門SE事業室のSTLプロジェクトに参加してクラウド構築全般を担っています
http://www.s-re.jp/renaissance/stl/
4
5. Serverlessとの出会い
● 2015/6月
● 初lambdaの実戦投入。最初はBEデータ処理
● ログが見にくいとか、エラー理由が分からないとかと遭遇していきました
● 2016/6月
● FrontのサービスとしてはまだRailsとかのほうがいいんじゃないのと思ってました
● 実際 STLテストマーケ実施時はEB + Railsで構築していました
● 2016/8月
● 今はなき JAWS UG Chiba にてServelessConfのセッションを聞いて衝撃
● => Frontも全部Serverless に染まるのも時間の問題と確信
● 急いでAWS のソリューションエンジニアとアーキテクチャ議論
● 2016/10月
● Serverless Conf Tokyoでアーキテクチャの方向性チェックして,
Apex,Swagger,Stagename 周りをdeployフローにくわえました
5
8. STL System構成
受付
スタッフ
スクール会員
様
Amazon
RDS(Aurora)
STL DB
Browser
play
sync Lesson & User
data
...
Shot upload
マイカルテページ
ログイン
off lesson
on lesson
SONY Smart Tennis Lesson System
court-Tablet
court
Server
BT:Shot Data
Video, data streaming
Get lesson, player
Post shot
生徒、レッスン、コーチ
バッチ同期
Tennis School Own System
受付-Tablet
Video,
HTML,JS
bucket
B2B
bucket
Amazon API
Gateway
App
lambda
Amazon
CloudFront
Tennis School DB
業務
Browser
AWS STS
コーチ
テニスコート
Cognito
Backend
lambda
「Full Serverless構成で、 SQL DB on VPCを
使用しているところが特徴です」
8
10. Serverless でもTest First! CI整備に汗をかく!
● Lambda 実行環境 NodeJS6.10
● LocalTest環境整備
● PullReq & Merge で自動Test
● LocalTest, APITestは
同じテストコードで両立させる
● API GW のIAM認証もSigV4Clientを
いれて実行可能
Local開発
•LocalTest作成:
mocha&istanbul
•Code実装
Pull Request
• lint: eslint
• Local Test on
Jenkins
• Coverage計測:
Istanbul
Deploy
• MasterMerge契機
• CI環境へDeploy:
apex
• API Test: mocha
Release
• labelを指定: apex
• Staging最終test:
mocha
• Custom Domain
Switch: APIGW
Appendix: “Test Knowhow”, “CI実現Jenkins file例” を参照
10
11. Lambda 運用監視のお手軽構築テンプレをつくる
独自Logger-> CloudwatchLogs -> MetricFilters -> Alarm -> SNS ->
● 標準lambda log だけだと見にくい、探しにくいので、
独自Loggerで必要項目を必ず出力しています
● MetricFilters, Alarm, SNSはセットで構築できるCloudFormationをテンプレートで用意
class MyLogger {
constructor (lambdaAliasName, lambdaVersion, requestId, resourcePath, httpMethod, logLevel) {
this.isMute = this.checkMuteEnvVar();
Object.assign(this, {lambdaAliasName, lambdaVersion, requestId, resourcePath, httpMethod});
this.logLevel = logLevel || 'info';
}
...
アラート管理は
お好きなSaaSを
Appendix: ManagedServiceごとの監視項目例 を参照 11
14. Serverless に SQL (Aurora) を組み合わせることについて
● 本来はServerlessには SQL(Aurora)は不向き(何度も言われました、、)
○ 不向きな理由1.
いくらでもScale するFrontに対してConnection limitが必ず存在するDB
○ 不向きな理由2.
VPC Lambdaを使わないといけない
● でも、、、
○ 既存システムがSQLDBで
○ BtoC でなく、BtoB である程度アクセス負荷が読める状況で
○ さらに API GW を前に立てて(同時接続limitを設けられるので、)
○ VPC Lambdaに対するケアもきちんとできるなら(後述)
「Serverless と、 SQL のおいしいとこ取りも可能です。」
14
16. 認可、権限コントロール も、
Cognito + SQL で強力かつ柔軟
強力に守ることはCognito, API GW に任せる
● Cognitoでの認証フローで役割ごとの STS:accessKey を付与
● 役割ごとに呼び出せるAPIGWのパスをIAM role policy定義としてDBに保存
● DOS攻撃などはAWSのレイヤでブロックしてもらう
柔軟に表現したいところは、SQLの関連としてチェックする
● どのコーチがどの生徒のデータを参照できるか等App仕様に依存するもの
● 構造化された関連を辿って表現したいものなどSQLであれば1行で自然に表
現できる
Appendix: Cognito + APIGW + STS 認可シーケンス参照
AuroraCognito STS
16
18. VPC Lambda
● Aurora(RDS) をつかう以上 VPC そしてVPC Lambda も必須
● API Call からDataにたどり着く までのみちのり
1. ClientCall
2. API GW (Cloudfront)
3. ENI作成
4. VPC Lambda 起動
5. Lambda handler invoke
6. Aurora(DB subnet)
「 Localでは100msec程度で終わる処理が、API経由だと1秒以上応答がかかる、
ときどき10秒以上、、Serverlessよ、こんなもんなのか、、、」
18
19. VPC Lambda ENIの仕組みを知る
● 分析:そもそもどこの段階で時間を使っているのか切り分けたい
● ENIの作られるタイミングが分からない!
● 「困ったときのCloudTrail! 」(Managedな裏側を垣間見る)
● CloudTrailのログからCreate/Delete NetworkInterface を検索
○ API応答が極端に遅かった時(ENIの生成は10秒以上かかる)、ENIが生成されているかを把握
● 対策:定期的に(5-10分間隔)ENI、Lambdaを暖機
● 参考:VPC ENI, Lambdaがどこまでスケールするか、EC2の制限が関係します。
○ ENIの数はEC2 のインスタンス数制限の5倍か、350 のどちらか大きい方です
○ http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Appendix_Limits.html
Appendix: ENI Tips参照 19
21. Lambda 対策 Tips メモリ けちるべからず
● Memoryを多く設定することでLambdaが稼働するインスタンスタイプが上がる
● CPUに依存した処理でも単純に設定メモリを倍にすれば倍早くなる可能性あり
● 課金は、100msec 単位なのでそれ以上処理にかかっている場合は
とりあえずメモリ設定上げて計測してみよう」
「メモリ倍にして、処理時間が半分になればコストも変わらない」
21
22. まとめ (今日の発表内容振り返り)
●汗
Serverelessに適合させた テスト、運用 !
●友情
既存SQLスキルをデータ連携、グループアクセス制御 で活用!
●勝利
lambdaのパフォーマンス向上!
「 SQLベースのB2B2C という固めの案件にもServerlessは適用できる。
既存のベストプラクティス ( テスト、運用設計、SQL) をServerless
styleに適合させることが重要。今後も良かった事例、失敗した事例共
有していきましょう!」
22
23. 最後に
● IoT, Robotics, Industry4.0, Serverless
全部できるのはソニーです。
https://www.sonynetwork.co.jp/corporation/recruit/careers/
23
25. Test Knowhow
自動テストを作るときに気をつけていること
● UTよりIT(IntegrationTest,API level test)の自動化のほうに重きをおいてます
顧客と合意する仕様レベルでテストもつくることで、テストコードの保守が
容易(あまり細かい単位で作りすぎると実装をかえるたびにテストコードも
一部修正が必要になりただの裏返しになることが多いため)
● UT, IT で同じようなテストコードを2回書かない
● 量より質 => テストカバレッジ C0,C1まで計る
○ istanbulでcoverage測定
● IT, UT両方のテストの合算のカバレッジを取れるようにして、既存のITで通せ
ないテストをUTで追加し、カバレッジ向上させる
//istanbul, mocha + sinon + power-assert を使用
istanbul cover _mocha tests.js
25
26. CI実現Jenkins File例
node {
timestamps {
sshagent([‘zzz’]) {
ansiColor(‘xterm’) {
timeout(time: 900, unit: ‘SECONDS’) {
def currentPath = pwd()
env.PROJECT_PATH = 'zzz'
env.REGION = 'us-west-2'
stage('テスト環境準備') {
sh '.jenkins/tests/prepare/install-npm.sh'
}
parallel(
lint: {
// Lint実行
stage('[並列実行] Lint') {
sh '.jenkins/tests/lint/lint.sh'
}
},
localIt: {
stage('[並列実行] Local IT事前準備') {
sh '.jenkins/tests/it/prepare/reset.sh'
}
stage('[並列実行(後続)] Local IT実施') {
sh '''
set -vxue
STATUS=0
cd ${PROJECT_PATH}
./measure-coverage.sh > results/local-it.log ||
STATUS=1
exit ${STATUS}
'''
archiveArtifacts(
allowEmptyArchive: true,
artifacts: ''’zzz'''
)
}
},
failFast: false
)
if(env.BRANCH_NAME == 'develop' ||
env.BRANCH_NAME ==~ /^release-.*/) {
stage('開発環境へのDeploy') {
sh '''
set -vxue
cd ${PROJECT_PATH}
apex deploy -r ${REGION} -C ../../ -a ci-jenkins
'''
}
stage('API IT事前準備') {
sh '''
set -vxue
# Lambda起こし
apex invoke -C ../../ -a ci-jenkins coaching-front || :
'''
}
stage('API IT実施') {
sh '''
set -vxue
STATUS=0
./it/smart-tennis-lesson-front/api-test.sh >
${PROJECT_PATH}/results/api-it.log || STATUS=1
cat ${PROJECT_PATH}/results/api-it.log
exit ${STATUS}
'''
}
26
27. ManagedServiceごとの監視項目例
● Lambda
● Aurora
Lamda全体
イベントまたは API 呼び出しに応じて呼び出される関数の回数
関数 (応答コード 4XX) エラーが原因で失敗した呼び出しの数
関数コードが実行を開始してから関数の実行が停止されるまでの実
時間
同時オペレーションを超える呼び出しレートのために調整された
Lambda 関数の呼び出し試行の回数
WARN Sum 60 1 <= 10
Lambdafront
イベントまたは API 呼び出しに応じて呼び出される関数の回数
関数 (応答コード 4XX) エラーが原因で失敗した呼び出しの数 ERROR Sum 60 1 <= 1
関数コードが実行を開始してから関数の実行が停止されるまでの実
時間
WARN Average 60 800 < 1
同時オペレーションを超える呼び出しレートのために調整された
Lambda 関数の呼び出し試行の回数
ERROR Sum 60 1 <= 5
Lambda Function ログの監視 Fatal レベル FATAL Sum 60 1 <= 1
Error レベル ERROR Sum 60 1 <= 1
Warn レベル WARN Sum 60 10 <= 1
監視対象 監視内容
Alarm 詳細
通知
レベル
Statistic
Period
(sec)
Threshold Evaluation
PeriodsValue
Comparison
Operator
DB インスタンスによって使用される CPU のパーセント
(CPU Utilization)
ERROR Average 60 80 <= 2
使用可能な RAM の容量
(Freeable memory)
ERROR Average 60 1048576 >= 1
各 DB インスタンスが一時テーブルとログのために使用できるスト
レージの量
(Free local storage)
ERROR Average 60 2147483648 >= 1
DB インスタンスへのアクティブな接続の数 (docではTotalConnections
になってる)
(DB connections)
ERROR Average 60 10 <= 2
1 秒あたりのデータベース内のデッドロックの平均回数
(Deadlocks)
ERROR Maximum 60 1 <= 1
27
28. NodeJsでのSQL DB マイグレーション
● Javascriptのmysql library Sequelize をつかっています
● 当初は https://github.com/BurntSushi/erd で
ER図定義してから -> Schema 定義にスクリプトで変換してました
● 最終段で 今後migration管理していくために、
Sequelize4 のmigration方式を採用。
差分から作成する方式へ変更 (rails的なもの)
$ sequelize db:migrate # Run pending migrations.
$ sequelize db:migrate:undo # Revert the last migration run.
$ sequelize help # Display this help text.
$ sequelize init # Initializes the project.
$ sequelize migration:create # Generates a new migration file.
$ sequelize version # Prints the version number. 28
29. Aurora Tips1 Backup
● スナップショット取得はほぼ一瞬、当然一貫性あり。
● DBインスタンス単位で取得、復元 復元時には新DBインスタンスを作ってそこに復元する。
● DBインスタンス作成、スナップショット復元の操作は不可分。(今のProdで)1~3時間かかる。復元
はストレージとS3の間で直接行われるため、DBインスタンスタイプと復元に要する時間には相関
無し復元に要する時間は見積もり方法無し(AWS回答)
● 自動スナップショット
○ 最長35日前までの任意の時点を復元可能
○ 指定時刻に毎日スナップショットが取られる
○ スナップショット取得時間の直後に戻す場合、1時間(量によります)
○ 次のスナップショットの直前の場合、約3時間(量によります)
「数時間というのはReleaseTrouble発生時のリカバー時間として許容できないので
Migration などDBに影響のあるRelease時は、
別途Dumpをとって即時リカバーできる状態にしています」
29
30. Aurora Tips2 減らないStorage
● Auroraストレージの特徴は?
○ DBクラスタは1台の書き込み可能なDBインスタンスと0〜15台の読み込み専用DBインスタンスと
分散されたストレージノード群からなリます。 ストレージノード群は3つのAvailability Zonesに2
つずつ全体で6重化されます。 過半数のストレージノード(6台中4台)にアクセスできればDBインス
タンスは正常稼働できます。 DBスナップショットはストレージノード群とS3の間で直接機能しま
す。
● テーブルとストレージの関係は?
○ テーブルはストレージ上のファイルのように振る舞います。1テーブル1ファイルの構成になります。
このファイルは追記型のストレージとして使用されます。
○ UPDATE, DELETEされたレコードは論理的にはファイルに追加されるのみである。
○ 更新前、削除前のレコードはそのまま残され、その占める領域は再利用されない。
● Auroraのテーブルが消費するファイルを縮小できますか?
○ できます。ただし、ストレージに戻され再利用できるようになるだけでストレージ自体は縮小でき
ません。
○ テーブルを削除すると、対応するファイルも削除されストレージ上で再利用可能になる。
○ テーブルに対してoptimize table ...またはalter table ... forceを実行すると有効なレコードだけが新
しいファイルにコピーされ、古いファイルは削除されストレージ上で再利用可能になる。
「とにかく減らないということを意識したDB運用を設計する」 30
31. Cognito+APIGW + STS認可シーケンス
user-1 ポリシー1
user-2 ポリシー2
:
ユーザの種類ごとに
使用できるAPIを
Policy定義する
1. authenticateUser(id, password)
ユーザid, password
STS
policies
AssumeRole (policies)
Temporary credentials
{
"Credentials": {
"AccessKeyId": "ASI*",
"SecretAccessKey": "dr/X*",
"SessionToken": "Fqo*",
"Expiration": "2016-11-04T13:42:56.000Z"
}
}
IdToken, RefresshToken, DeviceKey
2. getCredentials(IdToken)
UserPool
IdPool
Temporary credentials for auth
3. Temporary credentials for auth, ロール名
ユーザ別Credentials生
成・取得
cognito-identity-id
localStorage
Temporary credentials for API
4. Temporary credentials for API Policyにより認可
FunctionAPIやS3, AWS IoTなどの呼出し
IdToken,
RefresshToken,
DeviceKey
localStorage
Temporary credentials
31
32. VPC Lambda ENI Tips
● ENIの生成10秒以上かかる。定期的に(5-10分間隔)ENI、Lambdaを暖機しておくこ
とで 、 lambda実行開始までの時間を100msec 程度にできます
● それでも負荷があがってくると、ENI, Lambdaがスケールするタイミングで10秒程度
待たされることはあるタイムアウトの設定、リトライ要設計
● ENIの上限に達するとスケールもされません
● VPC ENI, Lambdaがどこまでスケールするかについて、EC2の制限が関係します。
○ ENIの数はEC2 のインスタンス数制限の5倍か、350 のどちらか大きい方です
○ http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Append
ix_Limits.html
● 必要なENIのキャパシティ計算方法
Projected peak concurrent executions * (Memory in GB / 1.5GB)
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc.html
32
33. Lambda 初期化処理 Tips
「毎Handler での初期化をやめ、グローバルにスキーマオブジェクトを保持する」
● 気をつける点
○ context.callbackWaitsForEmptyEventLoop = false; に設定する
○ DBへの接続エラーや、DBの接続先設定の変更時に永続オブジェクトの初期化をし直す
● 備考
○ Lambdaは 1コンテナ = 1プロセス の中でイベントハンドラを利用してイベントを待機している
○ 1コンテナ内で複数のリクエストを順番に処理している、負荷が上がるとコンテナがスケールする
○ Lambdaがスケールする単位は コンテナ 単位で、コンテナはリクエストが来ている限り落ちること
はなく生き続ける
○ 一般的なLambdaベストプラクティスとして、スケール時のレイテンシー低下を抑えるために初期
化処理は最小限にしておけ、というのがありますが、どうしても初期化がおもい場合ではこのよう
なテクニックにしたほうが全体のパフォーマンスは向上します。
33
37. Jenkins Auto Healing Tips Elastic Beanstalk(EB)
● efs-mount.sh
container_commands:
efs-mount:
command: |
/bin/bash .ebextensions/efs-mount.sh
#!/bin/bash
# Define variables
readonly AZ=$(curl -s http://169.254.169.254/latest/meta-
data/placement/availability-zone)
readonly EFS_ID=$(head -n1 .ebextensions/efs-id.txt)
...
# mount directory.
mount ¥
-t nfs4¥
-o
nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 ¥
${AZ}.${EFS_ID}.efs.${REGION_NAME}.amazonaws.com:/ /data/jenkins
# change owner of directory.
chown 1000:1000 /data/jenkins
# docker restart.
service docker restart
● .ebextensions/hoge.config
● Serverless じゃなく、EB (Docker type) + Jenkins2.0 docker imageで構築しました
● コスト抑えるため ELBなし、EC2の1台構成
● EB はAutoScaling Groupを作ってくれるのでMax,Min1にすると調子悪くなったら
Terminateすれば自動で立ち上げてくれます
● .ebextensionsというファイルを一緒にEBにDeployすると
起動時に行いたいことをカスタマイズできます
37
38. Serverlessにしなかった呪い1
EFS は 容量によってspeed 制限があるよ!
● しらずにlimitかかると 死にます
● npmインストールを定期実行すると、EFSの制限によってスループットが
10kb/sくらいに・・・。Jenkins激遅化の原因となった
All file systems, regardless of size, can burst to 100 MiB/s of throughput, and
those over 1 TiB large can burst to 100 MiB/s per TiB of data stored in the file
system. For example, a 10 TiB file system can burst to 1,000 MiB/s of
throughput (10 TiB x 100 MiB/s/TiB). The portion of time a file system can
burst is determined by its size, and the bursting model is designed so that
typical file system workloads will be able to burst virtually any time they need
to.
http://docs.aws.amazon.com/ja_jp/efs/latest/ug/performance.html 38
Notas do Editor みなさん、SONYのスマートテニスセンサーをご存知のかどれくらいいらっしゃいますでしょうか?
ありがとうございます 意外とXXですね
ここに本物があります。 こちら2014年に日本でB2Cとして発売を開始、その後2015年に全世界で販売をひろげおります
個人のお客様がご自分のスマホでテニス動画をとり、そのときの動画とともに ショットの種類、 ラケットの当たった位置、
ラケットをふるスィングスピード、 ショットデータがてもとにのこる。 動画を取ってないときもショット情報がのこり、
何級どのくらいの場所でうったのかというのが振り返ることができる画期的な商品で,沢山のテニスプレーヤにご愛用いただいていています。
昨年度その体験をテニススクールむけにさらにつくりこんだら、すごいものがつくれるのではないかと
日本最大手のテニススクールルネサンス様と共同開発したものがSmartTennis Lessonになります
スマートテニスレッスン こちら、どうして導入することになったのかを簡単にまとめました。
まず、Lambda自身は 出た当初2015/6からちょこちょこ実戦投入しておりました。
そこで、ログや監視をどのようにすればよいのかは 把握しておりました,
ただFrontのAPI サーバーとして導入するのはなんとなくまだ早いんじゃないかと漠然と感じていました
しかし、去年の丁度8月ですね。 吉田さんがUSで行われたServerless Confの参加レポートを発表してくださっているのを聞いて
PaaS でHerokuを知ったとき、もしくはCloudformationでInfraAs aCodeを実現できると感動した時と同じような衝撃をうけました。
内部的にはすぐにServerless Architecture へ乗り換えの設計を開始しました。大企業のは悪いときもあればいいときもあってAWS あらきさん、西谷さんという最強ソリューションエンジニアにレビューしてもらいながら設計をすすめ、10月のConf Tokyoで あらたにしったツールや、Tipsを加えて基本設計を短期間でつくりあげることができました。
私が去年設計時点で感じていた期待を大きい順に紹介します と、ここまで説明したところで すでに XX分ですね。 あと40ページほどあるんですが、、完全に時間配分を失敗しました。
適当にながして説明します。 資料はあとで公開しますので 飛ばしたところはよければ後で読んで見てください 生徒さん こちらがSTLの全体構成です 下半分に大きく転戦で囲まれている中がメインとなるシステムです。
左側のテニスコートと書かれているなかに書かれている コートサーバ、カメラ、タブレット、テニスセンサーが
それぞれのテニスコートに配置されているデバイスになります。この1セットが 全国各地数十面に配置されています。
その右側におなじみのAWS Serverless アイコンズ がならんでいるところが私が構築をしているものになります。
代表的なもので 認証にはCognito , API にはAPI GW + Lambda, WebAppの配信にはS3
VPC , RDS(Aurora) を導入しているところに特徴があります。
Serverless時に、AWSの推奨はKeyValue(Dynamo)
Nodeつかってる
LocalでLambda開発するときにテストデータをLambdaのEventParamとあわせる 既存のDBが
1からNode でScriptでチェックするのは大変、 このあたりは明らかにSQLのメリットをいかしたい Koこんな経路をとおってます Appendix Lambdaがよばれるたびにおいていたの 今後もみんなでみつけたベストプラクティを