容量が限られているDynamoDBデータインジェクションの最適化
最近、データインジェクションのタスクがありました。これは、S3から大量のソースファイルを読み込み、その情報を読み込んで、Amazon DynamoDBに書き込むというものです。ここでは、私たちが解決策を見出すために検討したことを紹介します。
- S3ソースファイルの総数は約1500個、各ファイルには400万行が含まれていたので、DynamoDBには60億回書き込まなければなりませんでした。
- Amazon DynamoDBの書き込みは高価です。100回/秒の書き込みで3000ドル/月)そのため、容量を超えたものは失われてしまうので、書き込み速度をコントロールする必要がありました。
- 私たちのアプリケーションは、Kubernetesで管理されたポッドで動作します。それぞれのポッドが完全に活用されていることを確認したかったのです。
- それぞれのアプリはマルチスレッドのJavaプログラムで、これは物事をより複雑にしますが、タスクをできるだけ早く終わらせるのに役立ちます。
ここでは、DynamoDBの書き込み容量、ポッド数、スレッド数の関係を紹介する。
Writing Capacity(writes/second) = (number of threads) * (number of pods) * (number of rows each thread can handle per second)
とても簡単なことですが、この方程式が満たされていることを確認する方法が必要です。Guavaライブラリ(https://github.com/google/guava)が真っ先に思い浮かびます。これは、よく設計されたレートリミッターを備えており、DynamoDBへのすべての書き込みの前に呼び出すことができます。例えば、以下のようになります。
int numberOfWritesPerSecond = 100;
RateLimiter limiter = RateLimiter.create(numberOfWritesPerSecond)。
limiter.acquire()
updateDynamoDB()です。
これで、方程式はよりシンプルになりました。
Writing Capacity(writes/second) = (number of writes on Rate limiter)* (number of pods)
見た目は良いのですが、実際にテストしてみると問題がありました。
- Amazonに3000の書き込み容量を設定し、Kubernetesに5つのポッドを設定し、各ポッドに5つのスレッドを与えたとすると、1つのシングルスレッドでは3000 / 5 / 5 = 120 (writes per second)となり、1つのソースファイルは1つのスレッドでしか処理できず、400万レコードあったので、1つのファイルを終えるのに、400万 / 240 = 33333秒、つまり9時間かかることになります。
- ファイルの1行に対して、S3からの読み込みとDynamoへの書き込みの2つの操作があるため、実際には9時間よりもさらに長くなります。S3からの読み込みとDynamoへの書き込みの2つの操作があるため、遅い方の操作で実際の時間が制限されます。
- このように処理時間が長くなると、S3接続がタイムアウトしたり、スレッドプールがタイムアウトしたり、Kubernetesが再起動したりする可能性があります。このように、ジョブが失敗する原因はたくさんあります。
- 書き込み容量を増やしても効果はありませんでした。シングルスレッドの容量は、ファイルの読み込みとDynamoの書き込み速度によって制限されています。各ファイルはまだ故障する可能性が高い。
問題を解決する方法を紹介します。
- このファイルを注意深く観察した結果、小さなアグリゲーションができることがわかりました。4行ごとに1つの行にまとめて、一緒にDynamoDBに書き込むことができました。400万回の書き込みが、いきなり100万回になりました。
- Dynamoの書き込み制限を克服するために、Dynamoの非同期操作に変更しました。現在、唯一の制限はファイルの読み取りでした。ポッド内のスレッド数を調整することで、最適なCPUユーティリティを得ることができました。
- 1つのファイルをマルチスレッドで読みます。
最初の3つの変更を行った後、1つのファイルは2時間以内に仕上げることができました。
結論
このタスクでは、アプリケーションのスループットをコンテナクラスタで制御する方法について、深く理解することができました。Kubernetesはコンテナのオーケストレーションを容易にしますが、同時にアプリケーションに複雑さをもたらします。クラウドベースのデータベース(Dynamo)はメンテナンスコストを削減しますが、その制約下でアプリケーションが正常に動作していることを確認するために余分な作業が必要になります。