どうもこんにちは。
DynamoDBがオンデマンド(リクエスト数課金)を選択できるようになり 本当に涙が出そうなくらい喜んだ わんこ。 です。
HAROiDでは、TV番組のプレゼント応募の仕組みなどを運用していたりもします。 このプレゼントの運用がなかなか曲者で…色んな番組や特番、または定常的にWebからの応募も受け付けるというものでして…
設計段階で、できれば 大型特番とか被っても大丈夫なスケーラビリティあふるる設計に という要望がありました。
そのためプレゼント企画ごとにDynamoDBを分けてしまい、その企画規模にあったスケールを行っていたのですが…
めちゃくちゃむずい
視聴率や告知のタイミングによっては想定の30倍くらいのリクエストになることもあったり、はたまた逆もあったり…。 でも心配だから大きめにスケールしておいて番組終了時にまた下げる…なんてことをやってたんですが…そこに女神のごとく降臨したオプションが…
BillingModeのPayPerReuqustですよ!!!!
いや、ほんと神様は見てくれてるんだなって思いました。 この発表の前日でも某音楽番組のプレゼント企画を行っていて、90個以上のテーブルのスケール作業や監視作業を行っていました。
TV番組での連動だと、負荷ってほんとに高スパイク短時間なので、スケールしているほとんどの時間はリクエストがない状態です。
もう、ね?完璧にこのプロダクトのためにリリースしてくれたんだな。って思いました。
ってことで早速負荷検証してみたいと思いまして、さくっと 千手観音 でぶん殴ってみました。
APIでの設定
- aws-sdk-goでは対応済み (2018/11/30 12時現在)
dynamodb.CreateTableInput
のBillingMode
にdynamodb.BillingModePayPerRequest
を設定BillingModePayPerRequest
とProvisionedThroughput
は同時に設定できない(当たり前- このモードでは
ProvisionedThroughput
は0
として返ってくるので注意が必要 - UpdateTableで同様に既存のテーブルに対しての変更も可能
こんな感じにするだけです。めっちゃ簡単。
input := &dynamodb.CreateTableInput{ TableName: aws.String(tableName), AttributeDefinitions: []*dynamodb.AttributeDefinition{ { AttributeName: aws.String("user_hash"), AttributeType: aws.String("S"), }, }, KeySchema: []*dynamodb.KeySchemaElement{ { AttributeName: aws.String("user_hash"), KeyType: aws.String("HASH"), }, }, BillingMode: aws.String(dynamodb.BillingModePayPerRequest), }
限界性能
- リリースノートでは 数千Request/Sec にも対応可能とあった
- このプロダクトのALBの暖気申請をしていなかったので1000rpsで打ち止めを食らう
- その時点でRead/Writeともに800-900capacityレベルのスループットは出ていた
- どのくらいの負荷で頭打ちもしくは性能劣化するかは後日また調査
コスト感
- Write request units $1.427 per million write request units
- Read request units $0.2854 per million read request units
安すぎませんかね!?(東京リージョンの価格
awscliは未対応?
awscli(1.16.60)ではまだPayPerRequestの設定を見つけられませんでした (もし間違ってたら教えてください
ざっくり感想
- 定常的にはリクエスト来ないテーブルの待機コストより断然お得
- 負荷が見積もりにくいものに対してはとても有効
- 頭打ちする性能次第ではかなり応用が効きそう
- 既存のものにもすぐ設定できるので素晴らしい
- もう負荷試算とかスケールの対応しなくていい
- まじ神アップデートでした
と、勢いだけでやってみたので今夜の番組から本番投入してみます。 来週くらいには性能検証とか細かいネタで書こうと思います。