Dynamic DynamoDB を使ってみた
はじめに
Amazon DynamoDB はとても便利で使い易いサービスですが、
テーブルへの書き込みや読み込みの容量に伴って、スループットを調整する必要があります。
今のところ AWS ではこの調整を自動でやってくれる(オートスケールの)機能はありませんが、
オープンソースで提供されているツールでこれを実現することができます。
そのうちの一つがこの記事で紹介する Dynamic DynamoDB です。
インストールと初期設定
インストールは CloudFormation テンプレート *1
を使って行うことも出来ますが、今回は手動でインストールしてみました。
Dynamic DynamoDB は Python 製なので、pip で簡単にインストールできます。
OS は Amazon Linux(Amazon Linux AMI 2014.03) で試しました。
# easy_install pip # pip install dynamic-dynamodb # dynamic-dynamodb --version Dynamic DynamoDB version: 1.18.3
必要なディレクトリを作成。
# mkdir /etc/dynamic-dynamodb && cd /etc/dynamic-dynamodb # mkdir logs
起動スクリプトを作成。
/etc/rc.d/init.d/dynamic-dynamodb
#!/usr/bin/env bash ### BEGIN INIT INFO # Provides: dynamic-dynamodb # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Automatic scaling for AWS DynamoDB # Description: Dynamic DynamoDB provides automatic scaling for AWS DynamoDB ### END INIT INFO NAME=dynamicdynamodb DAEMON=/usr/bin/dynamic-dynamodb DRY_RUN=$2 DAEMON_START_ARGS="--config /etc/dynamic-dynamodb/dynamic-dynamodb.conf --daemon start" DAEMON_STOP_ARGS="--config /etc/dynamic-dynamodb/dynamic-dynamodb.conf --daemon stop" SCRIPTNAME=/etc/init.d/$NAME SERVICE_LOG_FILE=/etc/dynamic-dynamodb/logs/service.log if [ "$DRY_RUN" == "--dry-run" ]; then DAEMON_START_ARGS="--config /etc/dynamic-dynamodb/dynamic-dynamodb.conf --dry-run --daemon start" DAEMON_STOP_ARGS="--config /etc/dynamic-dynamodb/dynamic-dynamodb.conf --dry-run --daemon stop" elif [ "$2" != "" ]; then echo "$2" echo "Second parameter has to be --dry-run and is used only when running start/restart/force-reload commands" exit 1 fi # Exit if the package is not installed [ -x "$DAEMON" ] || exit 1 . /etc/rc.d/init.d/functions log(){ timenow=`date +%Y-%m-%dT%H:%M:%S.%N` echo "$timenow: $1" echo "$timenow: $1" >> $SERVICE_LOG_FILE } error_exit(){ log "$1" exit 1 } do_start() { log "do_start:Starting $NAME" daemon $DAEMON $DAEMON_START_ARGS || error_exit "Failed in starting $NAME service" } do_stop() { log "do_stop:Stopping $NAME" daemon $DAEMON $DAEMON_STOP_ARGS || error_exit "Failed in stopping $NAME service" } case "$1" in start) do_start ;; stop) do_stop ;; status) status "$DAEMON" "$NAME" && exit 0 || exit $? ;; restart|force-reload) do_stop do_start #*) ;; *) echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 exit 3 ;; esac :
# chmod 755 dynamic-dynamodb # chkconfig --add dynamic-dynamodb
続いて config ファイルの設定です。
/etc/dynamic-dynamodb/dynamic-dynamodb.conf
[global] # AWS access keys (EC2 に IAM ロールを指定しているため使用しない) # aws-access-key-id: AWS_ACCESS_KEY # aws-secret-access-key-id: AWS_SECRET_KEY # AWS region to use region: ap-northeast-1 # How often should Dynamic DynamoDB monitor changes (in seconds) check-interval: 300 # Circuit breaker configuration # No provisioning updates will be made unless this URL returns # a HTTP 200 OK status code #circuit-breaker-url: http://my.service.com/v1/is_up #circuit-breaker-timeout: 500 [logging] # Log level [debug|info|warning|error] log-level: info # Log file (comment out to get only console output) log-file: /var/log/dynamic-dynamodb.log # External Python logging configuration file # Overrides both log-level and log-file # log-config-file: /path/to/logging.conf [table: ^sequences$] # # Read provisioning configuration # # Thresholds for trigging throughput alarm to send notification (%) reads-upper-alarm-threshold: 80 reads-lower-alarm-threshold: 30 # Enable or disable reads autoscaling enable-reads-autoscaling = true # Thresholds for scaling up or down the provisioning (%) reads-upper-threshold: 80 reads-lower-threshold: 30 # How many percent should Dynamic DynamoDB increase/decrease provisioning with (%) increase-reads-with: 50 decrease-reads-with: 50 # Units to increase or decrease reads with, must be either percent or units increase-reads-unit: percent decrease-reads-unit: percent # Maximum and minimum read provisioning # Dynamic DynamoDB will not provision any more or less reads than this min-provisioned-reads: 1 max-provisioned-reads: 100 # # Write provisioning configuration # # Threshold for trigging throughput alarm to send notification (%) writes-upper-alarm-threshold: 80 writes-lower-alarm-threshold: 30 # Enable or disable writes autoscaling enable-writes-autoscaling = true # Thresholds for scaling up or down the provisioning (%) writes-upper-threshold: 80 writes-lower-threshold: 30 # How many percent should Dynamic DynamoDB increase/decrease provisioning with (%) increase-writes-with: 50 decrease-writes-with: 50 # Units to increase or decrease writes with, must be either percent or units increase-writes-unit: percent decrease-writes-unit: percent # Maximum and minimum write provisioning # Dynamic DynamoDB will not provision any more or less writes than this min-provisioned-writes: 1 max-provisioned-writes: 100 # # Maintenance windows (in UTC) # #maintenance-windows: 22:00-23:59,00:00-06:00 # # Simple Notification Service configuration # # Topic ARN to publish notifications to # sns-topic-arn: arn:aws:sns:ap-northeast-x:xxxxxxxxx:dynamodb_alert # Message types to send as SNS notifications # # Comma separated list. Currently supported values: # - scale-up Get notifications when the table is scaled up # - scale-down Get notifications when the table is scaled down # - high-throughput-alarm Get notifications when exceed high throughput threshold # - low-throughput-alarm Get notifications when below low throughput threshold # sns-message-types: scale-up, scale-down, high-throughput-alarm, low-throughput-alarm # # Other settings # # Allow down scaling when at 0% consumed reads #allow-scaling-down-reads-on-0-percent: true #allow-scaling-down-writes-on-0-percent: true # Restrict scale down to only happen when BOTH reads AND writes are in need # of scaling down. Set this to "true" to minimize down scaling. #always-decrease-rw-together: true
非常に分かり易いパラメータとなっています。
上記の設定値をざっくりと説明すると…、
sequences というテーブル名に対して、300 秒おきにチェックを実施。
Read, Write ともに..
- スループットが 80% を上回ったら、SNS のアラートを送信。
- スループットが 30% を下回ったら、SNS のアラートを送信。
- 増減値は現在のスループットの 50% ごと。
- スループット下限値は 1、スケールダウンの際に SNS のアラートを送信。
- スループットの上限値は 100、スケールアップの際に SNS のアラートを送信。
という感じです。
起動
設定が済んだら起動してみます。
# service dynamic-dynamodb start
オートスケールを確認してみる
スループットが上がった時のログを確認してみます。
# tail -f /var/log/dynamic-dynamodb.log 2014-09-09 15:14:40,837 - dynamic-dynamodb - INFO - sequences - Changing provisioning to 5 read units and 12 write units 2014-09-09 15:14:40,891 - dynamic-dynamodb - INFO - sequences - Updating provisioning to 5 reads and 12 writes 2014-09-09 15:14:40,945 - dynamic-dynamodb - INFO - Sent SNS notification to arn:aws:sns:ap-northeast-x:xxxxxx:dynamodb
SNS からのメールも受信されてますね!
まとめ
非常に簡単なステップで DynamoDB のオートスケールを実現することが出来ました。
リクエストの増減が激しいユースケースや、そうじゃない場合でも、最初に設定する閾値がどれぐらいが妥当なのか測定する目的としても有用なんじゃないかと思います。
最後に、スケールダウンについては 1日4回まで しかできないのでその点は気をつけましょう!