YugabyteDBによるトークンバケットレート制限のスケーリング
10125 ワード
このシリーズでは、私は私の レート:1000トークン/秒(100 %トランザクション成功) レート:930トークン/秒 レート:124トークン/秒(100.00 %トランザクション成功)の50スレッドと同じ レート:218トークン/s(83 %トランザクション成功)、10のスレッドと同じです
yugabytedb雲
マネージドサービスを使用するのと同じ考えで、Yugabyte dbaasを通してAWS上で3ノードのyugabytedbクラスタを作成しました.
YugabyteDBは別の約束を読む
YugabyteDBシリアル化可能
この実行中の主要なパフォーマンスメトリックです.
1000個のysql ops/sは毎秒トークンの割合にマッチします.なぜなら、それぞれのトークンリクエストは1つのUPDATE文です 1000 OPS/sは、分散ストレージとトランザクション層のdocdbにおける操作の数です.そこでは、操作はRAFTプロトコルで3ノードに複製されます.ここでは、各更新プログラム.返り値はトランザクションのread + writeであり、1つの読み出しと1つの書き込みとして現れる.リターンが1つの操作であるために押し下げられるとき、若干のケースがあります、しかし、それは現在計算された値(YSQL層で計算が行われるので)にされません これらのアップデートの平均で5ミリ秒の待ち時間.テーブルがハッシュされているので 私は、圧縮がバックグラウンドで起こるとき、5 msから7 msまで潜在性の少しの増加を説明するためにコンパクトを示しました.すべての更新は、列の値とsstファイルのcompactionのための新しいバージョンとして格納されて以前のバージョンを取り除く. 我々は、この平均時間が5ミリ秒であることを確認しているPGRIGHT STATHERNステートメントに関する見解を持っています.
「ローカルブロック」統計はゼロです.なぜなら、一時テーブルはここに関係していません.yysqlがステートレスであるため、共有ブロックヒットを表示しません.PostgreSQLのコードは、テーブル操作メソッドの上でのみ再利用され、タプル操作をdocdb操作に変換します.
したがって、これは衝突なしでこのトークンバケットアルゴリズムを実行することについてです.パフォーマンスは、PostgreSQLと同じですが、スケールアウトする追加の可能性があります.負荷はここの3つのノードに分配されます、そして、1つのノードが計画されていない停電の計画されたメンテナンスのために下がるならば、複製因子RF = 3はすべて透過的に続きます.
PostgreSQL read readと同じです.
エラーが発生しました.
PostgreSQLシリアル化可能です.
もう一つは9869491.81/2149291 = 4.6 msであった
パフォーマンスメトリックは同じです.
夜の走りは真ん中(私は10本の糸で同じテストを始めた)
RateLimitDemo.java
同じ行の更新を伴わないAmazon RDSでのPostgreSQLのプログラム、read commitとserializableの分離.結果はid
読取り隔離レベルでsid
シリアル化可能な分離レベルid
読取り隔離レベルでsid
シリアル化可能な分離レベルyugabytedb雲
マネージドサービスを使用するのと同じ考えで、Yugabyte dbaasを通してAWS上で3ノードのyugabytedbクラスタを作成しました.
YugabyteDBは別の約束を読む
id
インマイRateLimitDemo.java
私は変更id
セッションpidを連結するには、次の手順に従います.rate_limiting_request(?||pg_backend_pid(),?)
そして、read - commitされた分離レベルを設定します.connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED)
java RateLimitDemo 50 "jdbc:yugabytedb://47cc8863-9344-4a9c-bc02-0dd9f843dceb.cloudportal.yugabyte.com/yugabyte?user=admin&password=Covid-19" "user2" 1000 20 | awk 'BEGIN{t=systime()}/remaining$/{c=c+1;p=100*$5/$3}NR%100==0{printf "rate: %8.2f/s (last pct: %5.2f) max retry:%3d\n",c/(systime()-t),p,retry}/retry/{sub(/#/,"",$6);if($6>retry)retry=$6}'
read commitはPostgreSQLの互換性のために用意されていますが、推奨されませんので、PostgreSQLと同じレートであることを示します.rate: 1063.08/s (last pct: 100.00) max retry: 1
rate: 1063.32/s (last pct: 100.00) max retry: 1
rate: 1063.56/s (last pct: 100.00) max retry: 1
rate: 1063.80/s (last pct: 100.00) max retry: 1
rate: 1064.05/s (last pct: 100.00) max retry: 1
rate: 1064.29/s (last pct: 100.00) max retry: 1
rate: 1064.53/s (last pct: 100.00) max retry: 1
rate: 1062.20/s (last pct: 100.00) max retry: 1
rate: 1062.44/s (last pct: 100.00) max retry: 1
rate: 1062.68/s (last pct: 100.00) max retry: 1
rate: 1062.92/s (last pct: 100.00) max retry: 1
rate: 1063.16/s (last pct: 100.00) max retry: 1
PostgreSQLとの違いは、悲観的なロックを使用して再試行していませんでした.YugabyteDBはここで楽観的にロックを使用します.YugabyteDBシリアル化可能
id
インマイRateLimitDemo.java
私は守るid
セッションpidを連結します.rate_limiting_request(?||pg_backend_pid(),?)
そして、read - commitされた分離レベルを設定します.connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE)
スループットは同じです.rate: 1079.99/s (last pct: 100.00) max retry: 2
rate: 1079.38/s (last pct: 100.00) max retry: 2
rate: 1079.44/s (last pct: 100.00) max retry: 2
rate: 1079.51/s (last pct: 100.00) max retry: 2
rate: 1079.57/s (last pct: 100.00) max retry: 2
rate: 1079.63/s (last pct: 100.00) max retry: 2
rate: 1079.69/s (last pct: 100.00) max retry: 2
rate: 1079.75/s (last pct: 100.00) max retry: 2
rate: 1079.81/s (last pct: 100.00) max retry: 2
rate: 1079.87/s (last pct: 100.00) max retry: 2
rate: 1079.94/s (last pct: 100.00) max retry: 2
rate: 1080.00/s (last pct: 100.00) max retry: 2
シリアル化可能なのは、右の分離レベルです.リトライ量はまだ少ない.この実行中の主要なパフォーマンスメトリックです.
id
を追加するid
これらの操作は、右のノード、タブレットリーダーに送られ、他のノードからの書き込みクォートを取得するのを待ちます(ここではマルチZの設定があります).「ローカルブロック」統計はゼロです.なぜなら、一時テーブルはここに関係していません.yysqlがステートレスであるため、共有ブロックヒットを表示しません.PostgreSQLのコードは、テーブル操作メソッドの上でのみ再利用され、タプル操作をdocdb操作に変換します.
したがって、これは衝突なしでこのトークンバケットアルゴリズムを実行することについてです.パフォーマンスは、PostgreSQLと同じですが、スケールアウトする追加の可能性があります.負荷はここの3つのノードに分配されます、そして、1つのノードが計画されていない停電の計画されたメンテナンスのために下がるならば、複製因子RF = 3はすべて透過的に続きます.
PostgreSQL read readと同じです.
id
今50レースでレース条件を強調するid
. インマイRateLimitDemo.java
私は戻ってid
ひとりぼっちrate_limiting_request(?,?)
そして、read - commitされた分離レベルを設定します.connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED)
rate: 126.99/s (last pct: 96.69) max retry: 4
rate: 127.59/s (last pct: 84.78) max retry: 4
rate: 127.39/s (last pct: 95.62) max retry: 4
rate: 127.17/s (last pct: 98.37) max retry: 4
rate: 126.97/s (last pct: 96.71) max retry: 4
rate: 127.58/s (last pct: 95.68) max retry: 4
rate: 127.38/s (last pct: 97.62) max retry: 4
rate: 127.15/s (last pct: 96.68) max retry: 4
rate: 127.76/s (last pct: 88.00) max retry: 4
rate: 127.54/s (last pct: 92.53) max retry: 4
rate: 127.34/s (last pct: 94.48) max retry: 4
rate: 127.91/s (last pct: 92.85) max retry: 4
rate: 127.69/s (last pct: 92.68) max retry: 4
rate: 127.50/s (last pct: 92.87) max retry: 4
rate: 128.02/s (last pct: 83.57) max retry: 4
rate: 127.78/s (last pct: 95.61) max retry: 4
rate: 128.33/s (last pct: 95.61) max retry: 4
rate: 128.14/s (last pct: 95.66) max retry: 4
rate: 128.74/s (last pct: 98.04) max retry: 4
rate: 128.51/s (last pct: 92.40) max retry: 4
rate: 128.29/s (last pct: 94.63) max retry: 4
ここでは、PostgreSQLのように、すべてのスレッドが同じ行を更新するように競合しているので、この速度は非常に低いです.最初に、1行だけがビジーです.第二に、リードコミットの分離レベルでも再試行があります.エラーが発生しました.
(pid@host [email protected]) 3771 calls 3487 tokens 3.8 /sec 60000 remaining
(pid@host [email protected]) 2706 calls 2460 tokens 2.6 /sec 60000 remaining
(pid@host [email protected]) 1513 calls 1422 tokens 1.5 /sec 60000 remaining
2022-01-05T23:00:26.369987Z SQLSTATE 40001 on retry #0 com.yugabyte.util.PSQLException: ERROR: All transparent retries exhausted. Operation failed. Try again.: Value write after transaction start: { physical: 1641423626346947 } >= { physical: 1641423625848215 }: kConflict
2022-01-05T23:00:26.371342Z SQLSTATE 40001 on retry #0 com.yugabyte.util.PSQLException: ERROR: Operation expired: Transaction aborted: kAborted
(pid@host [email protected]) 2568 calls 2482 tokens 2.7 /sec 60000 remaining
(pid@host [email protected]) 2272 calls 2186 tokens 2.4 /sec 60000 remaining
これは私のプログラムでキャッチしたもので、数ミリ秒後に再試行するが、データベースで自動的に再試行されたAll transparent retries exhausted
). これは、なぜそれがアプリケーションの再試行の数が少ないと遅いです説明します.PostgreSQLシリアル化可能です.
id
最後のテストRateLimitDemo.java
私は戻ってid
ひとりぼっちrate_limiting_request(?,?)
そして、read - commitされた分離レベルを設定します.connection.setTransactionIsolation(Connection.SERIALIZABLE)
前の結果を考えれば、私はPostgreSQLと同様にスレッド数を10に減らしました.ここでは秒単位で取得したトークンの割合を示します.rate: 116.60/s (last pct: 93.95) max retry: 8
rate: 116.60/s (last pct: 93.25) max retry: 8
rate: 116.60/s (last pct: 92.66) max retry: 8
rate: 116.60/s (last pct: 88.60) max retry: 8
rate: 116.60/s (last pct: 88.48) max retry: 8
rate: 116.60/s (last pct: 93.95) max retry: 8
rate: 116.59/s (last pct: 88.60) max retry: 8
rate: 116.59/s (last pct: 93.92) max retry: 8
rate: 116.59/s (last pct: 93.92) max retry: 8
rate: 116.59/s (last pct: 92.66) max retry: 8
rate: 116.59/s (last pct: 87.81) max retry: 8
rate: 116.59/s (last pct: 88.73) max retry: 8
rate: 116.59/s (last pct: 87.81) max retry: 8
rate: 116.58/s (last pct: 91.75) max retry: 8
rate: 116.58/s (last pct: 92.66) max retry: 8
rate: 116.58/s (last pct: 93.25) max retry: 8
rate: 116.58/s (last pct: 93.95) max retry: 8
rate: 116.58/s (last pct: 87.81) max retry: 8
rate: 116.58/s (last pct: 91.75) max retry: 8
rate: 116.59/s (last pct: 93.95) max retry: 8
同じ行のすべてのスレッドとの更新の競合を考慮した場合、スループットは低くなりますが、レイテンシは良いままです.rate_limiting_request(?,?)
1つもう一つは9869491.81/2149291 = 4.6 msであった
id
. はい、このレース条件では、スループットが低くなりませんが、RAMやCPUのデータの局所性を考慮して応答時間が高くなります.パフォーマンスメトリックは同じです.
夜の走りは真ん中(私は10本の糸で同じテストを始めた)
id
そして、より低いCPU使用量で、より現実的である異なるものの上の50の糸.あなたが少数のユーザーまたはテナントIDですべてのトークン要求でこのレース状態にいるならば、より高いスループットを必要として、このトークンバケツはスケーラブルではありません.次のポストに別のアルゴリズムを示します.Reference
この問題について(YugabyteDBによるトークンバケットレート制限のスケーリング), 我々は、より多くの情報をここで見つけました https://dev.to/yugabyte/scaling-token-buckets-rate-limiting-with-yugabytedb-4p1oテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol