AzureコスモスDBのためのCassandra APIを用いた耐故障性アプリケーションの構築
Azure Cosmos DB に基づいて、1秒あたりのオペレーションの特定の数を実行できるリソース管理システムですprovisioned throughput 設定してください.クライアントがその限界を超えてrequest units プロビジョニングされたものよりも、その後の要求とスローされた例外のレート制限につながる429 errors .
実際の例の助けを借りて、私はあなたのGo これらのレート制限エラーによって影響を受ける操作を取り扱って、再試行することによるアプリケーション.あなたが続くのを助けるために、このブログのためのサンプル・アプリケーション・コードは利用できますon GitHub - これはgocql driver for Apache Cassandra .
このポストでは、我々は行きます: サンプルアプリケーションを実行する前の初期設定と設定 各種負荷テストシナリオの実行と解析 リトライポリシー実装の簡単な概要. レート制限に取り組む1つの方法は、アプリケーション要件を満たすためにプロビジョニングされたスループットを調整することです.があるmultiple ways to do this , azureポータル、azure cli、cqlを使用します.
しかし、アプリケーション自体でこれらのエラーを処理したい場合はどうですか?
良いことはAzure Cosmos DBのためのCassandra APIがCassandraのネイティブのプロトコルの上でオーバーロードされたエラーにレート制限例外を翻訳するということです.以来
The Azure Cosmos DB extension ライブラリを使用すると、Javaアプリケーションでリトライポリシーを使用することは非常に簡単です.同等の囲碁版はavailable on GitHub また、このブログ記事のサンプルアプリケーションで使用されています.
約束通り、あなたは、シンプルで実用的な例を使用して、全体のプロセスを歩いていきます.概念を実証するのに使用されるサンプルアプリケーションは、残りのエンドポイントを公開するサービスです
このAPIサービスでいくつかの負荷テストを実行すると、制限制限がどのように現れるか、どのように処理されるかを見ることができます.
インストール開始 hey , 負荷試験プログラムOS固有のバイナリ(64ビット)をダウンロードできますLinux , Mac and Windows (参照) the GitHub repo 最新の情報については、ユーティリティをダウンロードして問題に直面する)
このgithub repoをクローンし、正しいディレクトリに変更します.
アジュールを作る Cosmos DB account と カサンドラ オプション
keyspaceとtableを作成するには、次のようにします
端末をオープンし、アプリケーションの環境変数を設定します.
順序が正常に格納されていることを確認します.あなたはhosted CQL shell in the Azure portal 以下のクエリを実行します.
残りのエンドポイントを300リクエストで呼び出します.これは、デフォルトで割り当てられた400 Ru/sしかないので、システムをオーバーロードするのに十分です.
Loadテストを開始するには、次の手順に従います.
クエリエラーの観測
簡単にするために、ログ出力をテスト/診断目的で使用します.クエリ実行中に発生したエラー(この場合は制限されます.)は、 gocql.QueryObserver . ランダムに生成された順序IDは、各エラーメッセージでログに記録され、失敗した順序が再試行されたかどうかを確認するためにログをチェックすることができます.
以下はコードスニペットです.
ロードテスト端末に戻って、統計のいくつかをチェックしてください(出力を簡潔にするために出力されました).
これは生のベンチマークテストではなく、我々は生産グレードのアプリケーションを持っていないので、あなたは無視することができます
最後の数字を確認しましょう.開ける カサンドラ azure cosmos db portalで同じクエリを実行します.
あなたのアプリケーションがそのスループットの約60 - 70 %で動作しているほとんどの時間を費やすならAutoscale provisioned throughput あなたのRu/Sとコスト使用量を最適化するのを助けることができないとき、使用中でないときにスケーリングすることによって-あなたは、あなたのワークロードが1時間単位で必要とする資源のためにだけ支払います.
だから、リトライポリシーなしで何が起こるか?
プレスを停止する
Azureポータルを使用してリクエストユニットを増やすことができます
リクエストの数を増やす
次のセクションではcustom Retry Policy 作品
公式ドキュメントからこれらのリソースをチェックしてください. Use cases and benefits of Autoscale provisioned throughput Details of the Cassandra API support in Azure Cosmos DB Get up and running with a Go application and Cassandra API for Azure Cosmos DB Frequently asked questions about the Cassandra API in Azure Cosmos DB Request Units concepts
実際の例の助けを借りて、私はあなたのGo これらのレート制限エラーによって影響を受ける操作を取り扱って、再試行することによるアプリケーション.あなたが続くのを助けるために、このブログのためのサンプル・アプリケーション・コードは利用できますon GitHub - これはgocql driver for Apache Cassandra .
このポストでは、我々は行きます:
しかし、アプリケーション自体でこれらのエラーを処理したい場合はどうですか?
良いことはAzure Cosmos DBのためのCassandra APIがCassandraのネイティブのプロトコルの上でオーバーロードされたエラーにレート制限例外を翻訳するということです.以来
gocql
ドライバを使用すると、プラグインのプラグインRetryPolicy , これらのエラーをインターセプトするカスタム実装を記述することができます.この政策はbe applied to each Query または、グローバルレベルで ClusterConfig . The Azure Cosmos DB extension ライブラリを使用すると、Javaアプリケーションでリトライポリシーを使用することは非常に簡単です.同等の囲碁版はavailable on GitHub また、このブログ記事のサンプルアプリケーションで使用されています.
ポリシーを再試行する
約束通り、あなたは、シンプルで実用的な例を使用して、全体のプロセスを歩いていきます.概念を実証するのに使用されるサンプルアプリケーションは、残りのエンドポイントを公開するサービスです
POST
AzureコスモスDBのCassandraテーブルに永続するデータを注文します.このAPIサービスでいくつかの負荷テストを実行すると、制限制限がどのように現れるか、どのように処理されるかを見ることができます.
事前の要件
インストール開始 hey , 負荷試験プログラムOS固有のバイナリ(64ビット)をダウンロードできますLinux , Mac and Windows (参照) the GitHub repo 最新の情報については、ユーティリティをダウンロードして問題に直面する)
You can use any other tool that allows you to generate load on an HTTP endpoint
このgithub repoをクローンし、正しいディレクトリに変更します.
git clone github.com/abhirockzz/cosmos-go-rate-limiting
cd cosmos-go-rate-limiting
AzureコスモスDBの設定
アジュールを作る Cosmos DB account と カサンドラ オプション
keyspaceとtableを作成するには、次のようにします
CQL
: CREATE KEYSPACE ordersapp WITH REPLICATION = {'class' : 'SimpleStrategy'};
CREATE TABLE ordersapp.orders (
id uuid PRIMARY KEY,
amount int,
state text,
time timestamp
);
アプリケーションを起動する
端末をオープンし、アプリケーションの環境変数を設定します.
export COSMOSDB_CASSANDRA_CONTACT_POINT=.cassandra.cosmos.azure.com
export COSMOSDB_CASSANDRA_PORT=10350
export COSMOSDB_CASSANDRA_USER=
export COSMOSDB_CASSANDRA_PASSWORD=
#optional (default: 5)
#export MAX_RETRIES=
アプリケーションを起動するgo run main.go
//wait for this output
Connected to Azure Cosmos DB
アプリケーションが予想通りに動作しているかどうかをテストするには、別の端末から残りのエンドポイント(各順序に1回)を呼び出していくつかの命令を挿入します.curl http://localhost:8080/orders
あなたがエンドポイントを起動しながら、それを入力する必要はありませんので、アプリケーションはランダムなデータを生成します順序が正常に格納されていることを確認します.あなたはhosted CQL shell in the Azure portal 以下のクエリを実行します.
select count(*) from ordersapp.orders;
// you should see this output
system.count(*)
-----------------
1
(1 rows)
あなたはすべて決めた.負荷テストを開始しましょう!
残りのエンドポイントを300リクエストで呼び出します.これは、デフォルトで割り当てられた400 Ru/sしかないので、システムをオーバーロードするのに十分です.
Loadテストを開始するには、次の手順に従います.
hey -t 0 -n 300 http://localhost:8080/orders
アプリケーション端末のログに注目してください.最初に、順序が正常に作成されていることがわかります.例えば、Added order ID 25a8cec1-e67a-11ea-9c17-7f242c2eeac0
Added order ID 25a8f5ef-e67a-11ea-9c17-7f242c2eeac0
Added order ID 25a8f5ea-e67a-11ea-9c17-7f242c2eeac0
...
しばらくして、スループットが低下し、最終的にprovisioned limitを超えるので、Azure Cosmos DBはアプリケーションリクエストを制限します.これは、以下のようにエラーになります. Request rate is large: ActivityID=ac78fac3-5c36-4a20-8ad7-4b2d0768ffe4, RetryAfterMs=112, Additional details='Response status code does not indicate success: TooManyRequests (429); Substatus: 3200; ActivityId: ac78fac3-5c36-4a20-8ad7-4b2d0768ffe4; Reason: ({
"Errors": [
"Request rate is large. More Request Units may be needed, so no changes were made. Please retry this request later. Learn more: http://aka.ms/cosmosdb-error-429"
]
});
In the error message above, notice the following: TooManyRequests (429) and RetryAfterMs=112
クエリエラーの観測
簡単にするために、ログ出力をテスト/診断目的で使用します.クエリ実行中に発生したエラー(この場合は制限されます.)は、 gocql.QueryObserver . ランダムに生成された順序IDは、各エラーメッセージでログに記録され、失敗した順序が再試行されたかどうかを確認するためにログをチェックすることができます.
以下はコードスニペットです.
....
type OrderInsertErrorLogger struct {
orderID string
}
// implements gocql.QueryObserver
func (l OrderInsertErrorLogger) ObserveQuery(ctx context.Context, oq gocql.ObservedQuery) {
err := oq.Err
if err != nil {
log.Printf("Query error for order ID %sn%v", l.orderID, err)
}
}
....
// the Observer is associated with each query
rid, _ := uuid.GenerateUUID()
err := cs.Query(insertQuery).Bind(rid, rand.Intn(200)+50, fixedLocation, time.Now()).Observer(OrderInsertErrorLogger{orderID: rid}).Exec()
....
どのように多くの注文を介して?ロードテスト端末に戻って、統計のいくつかをチェックしてください(出力を簡潔にするために出力されました).
Summary:
Total: 2.8507 secs
Slowest: 1.3437 secs
Fastest: 0.2428 secs
Average: 0.5389 secs
Requests/sec: 70.1592
....
Status code distribution:
[200] 300 responses
The numbers will differ in your specific case depending on multiple factors.
これは生のベンチマークテストではなく、我々は生産グレードのアプリケーションを持っていないので、あなたは無視することができます
Requests/sec
などが、我々の注意を引く Status code distribution
属性は、我々のアプリケーションはHTTP
200
for すべてのリクエスト.最後の数字を確認しましょう.開ける カサンドラ azure cosmos db portalで同じクエリを実行します.
select count(*) from ordersapp.orders;
//output
system.count(*)
-----------------
301
あなたは300を見るべきです 追加の行(命令)が挿入されている.キーテイクアウトは、すべての命令が正常にAzureコスモスDB DEに格納されていたことです-私たちのアプリケーションコードが透過的に我々が設定した再試行方針(コードの1行で)に基づいてそれらを再試行したので、レート制限エラーにもかかわらずclusterConfig.RetryPolicy = retry.NewCosmosRetryPolicy(numRetries)
動的スループット管理に関する一考察
あなたのアプリケーションがそのスループットの約60 - 70 %で動作しているほとんどの時間を費やすならAutoscale provisioned throughput あなたのRu/Sとコスト使用量を最適化するのを助けることができないとき、使用中でないときにスケーリングすることによって-あなたは、あなたのワークロードが1時間単位で必要とする資源のためにだけ支払います.
だから、リトライポリシーなしで何が起こるか?
ポリシーを無効にする
プレスを停止する
control+c
端末で環境変数を設定し、アプリケーションを再起動します. export USE_RETRY_POLICY=false
go run main.go
ロードテストを再度実行する前に、 select count(*) from ordersapp.orders;
hey -t 0 -n 300 http://localhost:8080/orders
アプリケーションのログでは、同じレートのエラーを制限通知されます.ロードテストを実行した端末では、出力の要約の最後に、いくつかの要求が正常に完了しなかったか、つまり応答がHTTP 200
...
Status code distribution:
[200] 240 responses
[429] 60 responses
リトライポリシーが実施されなかったため、アプリケーションはもはや再-レート制限のために失敗した要求を試みた.増加するスループット
Azureポータルを使用してリクエストユニットを増やすことができます
800
RU/s
) と同じロードテストを実行するhey -t 0 -n 300 http://localhost:8080/orders
あなたは ない レート制限(HTTP
429
) エラーは、現在のレイテンシーのための比較的低数、秒あたりのリクエストなど.リクエストの数を増やす
-n
スループットが閾値を取得するアプリケーションのために違反したときに参照してください.予想通り、すべての命令は首尾よく(エラーやリトライなしで)持続されます次のセクションではcustom Retry Policy 作品
This is an experimental implementation, and you should write custom policies to suit fault-tolerance and performance requirements of your applications.
舞台裏で
CosmosRetryPolicy
に付着するgocql.RetryPolicy 実装によるインタフェースAttempt
and GetRetry
関数. type CosmosRetryPolicy struct {
MaxRetryCount int
FixedBackOffTimeMs int
GrowingBackOffTimeMs int
numAttempts int
}
再試行は、その問い合わせの再試行回数がmax retry config以下の場合にのみ開始されます. func (crp *CosmosRetryPolicy) Attempt(rq gocql.RetryableQuery) bool {
crp.numAttempts = rq.Attempts()
return rq.Attempts() <= crp.MaxRetryCount || crp.MaxRetryCount == -1
}
GetRetryType
関数はエラーの種類を検出します.HTTP 429
), の値を取り出すRetryAfterMs
フィールド(エラーメッセージから)とクエリを再試行する前にスリープ状態に使用します. func (crp *CosmosRetryPolicy) GetRetryType(err error) gocql.RetryType {
switch err.(type) {
default:
retryAfterMs := crp.getRetryAfterMs(err.Error())
if retryAfterMs == -1 {
return gocql.Rethrow
}
time.Sleep(retryAfterMs)
return gocql.Retry
//other case statements have been omitted for brevity
}
Azure Cosmos DBは柔軟性を提供して、様々な方法を使用してスループット要件を設定し、調整するだけでなく、アプリケーションが制限制限エラーを処理できるようにする基本的なプリミティブを提供します.このブログのポストでは、どのようにGOアプリケーションのためにこれを行うことができますが、その概念は、任意の言語とそのそれぞれに適用されるCQL compatible Azure Cosmos DB用のCassandra APIで作業するためのドライバです.詳しく知る
公式ドキュメントからこれらのリソースをチェックしてください.
Reference
この問題について(AzureコスモスDBのためのCassandra APIを用いた耐故障性アプリケーションの構築), 我々は、より多くの情報をここで見つけました https://dev.to/azure/build-fault-tolerant-applications-with-cassandra-api-for-azure-cosmos-db-2m70テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol