Boto3

Boto3でDynamoDBに登録する

dbインスタンスでAWSのアクセスキーを指定して初期化。

1
2
3
4
5
6
7
db = boto3.resource(
'dynamodb',
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
region_name=os.environ['AWS_DEFAULT_REGION'],
)
table = db.Table(table_name)

itemに格納するデータをハッシュで入れていた場合、JSON形式にして格納すればいい。

1
table.put_item({k: v for k, v in item.items()})

Creates a new item, or replaces an old item with a new item. If an item that has the same primary key as the new item already exists in the specified table, the new item completely replaces the existing item. You can perform a conditional put operation (add a new item if one with the specified primary key doesn’t exist), or replace an existing item if it has certain attribute values. You can return the item’s attribute values in the same operation, using the ReturnValues parameter.

存在しない場合は追加され、既存のレコードがある場合はレコードが置き換えられる。置き換えたくない場合は条件付き操作で制御する。

batch_writer

複数のレコードを効率的に書き込むbatch_writer()がある。batch_writer()を使用すると、バッファリングと再送を自動的に行うことができる。エラーの場合に適宜待ち時間を挟んでリトライする。

1
2
3
4
def batch_put_table(table, records):
with table.batch_writer() as batch:
for record in records:
batch.put_item({k: v for k, v in record.items()})

Create a batch writer object.

This method creates a context manager for writing objects to Amazon DynamoDB in batch.

The batch writer will automatically handle buffering and sending items in batches. In addition, the batch writer will also automatically handle any unprocessed items and resend them as needed. All you need to do is call put_item for any items you want to add, and delete_item for any items you want to delete.

バッチライターは未処理のアイテムも自動的に再送を行う。追加の場合put_item()、削除の場合delete_item()を呼べばよい。

キャパシティを超えた時の動作

DynamoDBにput_item()で書き込んだ場合に、キャパシティユニットの上限値を超えるとHTTPステータスコード400のThrottlingException (Message: Rate of requests exceeds the allowed throughput.)を発生させる。

batch_writerを使用している場合、一時的な超過であればリトライによってリカバリーされるが、書き込み量に対してキャパシティユニットが知さすぎる場合は、リトライアウトしてしまい、書き込みエラーとなる。

DynamoDBのCloudWatchによる統計情報

  • 中央より左側が書き込み量の調整をせずbatch_writer()によって大量投入した場合の動作
  • 中央より右側が書き込むレコード数を適当な数毎に区切ってbatch_writer()に渡して処理した場合の動作

書き込みキャパシティーをみると、左側は割り当てた1を大きく超えて消費していることがわかる。
右側では統計情報上は1を超えているが、ThrottlingExceptionは発生しなかった。

AWS DynamoDB Statistics width=640

PUTのレイテンシーは平均値としてはばらつきが大きいが、似たような値である。

AWS DynamoDB Statistics width=640

合計値はリトライが減ったことにより右側が少なくなっている。

AWS DynamoDB Statistics width=640

スロットル書き込みはThrottlingExceptionが発生している状態である。左側は多発していることがわかる。

AWS DynamoDB Statistics width=640

AWS DynamoDB Statistics width=640