ダボにおけるタイムホイールアルゴリズムの応用

ダボにおけるタイムホイールアルゴリズムの応用

[[346568]]

1 スケジュールされたタスク

Netty、Quartz、Kafka、Linux にはすべてスケジュールされたタスク機能があります。

JDK に付属する java.util.Timer と DelayedQueue は、単純なスケジュールされたタスクを実装できます。基礎となるレイヤーはヒープを使用し、アクセスの複雑さは O(nlog(n)) ですが、大規模なスケジュールされたタスクをサポートすることはできません。

タスク量が多く、パフォーマンス要件が高いシナリオでは、タイムホイールアルゴリズムを使用して、タスクアクセスとキャンセル操作の時間計算量を O(1) に削減します。

2 タイムホイールモデルとその応用

スケジュールされたタスクを効率的にバッチ管理するためのスケジューリング モデル。これは通常、時計に似たリング構造として実装され、多くのスロットに分割され、1 つのスロットは時間間隔を表し、各スロットは双方向リンク リストを使用してスケジュールされたタスクを格納します。

ポインタは定期的にジャンプし、スロットにジャンプすると、そのスロットのタイミング タスクが実行されます。

ハッシュタイミングホイール構造図

  • 障害回復
  • フロー制御
  • スケジューリングアルゴリズム
  • ネットワーク内のパケットのライフサイクルを制御する

タイマーの維持には費用がかかる

  • プロセッサはクロックごとに中断される
  • きめ細かいタイマーを使用する
  • 未完成のタイマーが多数あります

全体的な割り込みオーバーヘッドを削減するには、効率的なタイマー アルゴリズムが必要です。

単層タイムホイールの容量と精度には限界があります。特に高い精度が求められるシナリオ、特に長い時間範囲、またはスケジュールする必要のある大量のタスクがある場合、通常は、マルチレベル タイムホイールと、永続ストレージとタイムホイールを組み合わせたソリューションが使用されます。

モデルとパフォーマンスの指標

モデルのルール

クライアントからの呼び出し:

  • START_TIMER(間隔、リクエストID、有効期限アクション)
  • STOP_TIMER (リクエストID)

タイマーティック呼び出し:

  • ティックごとのブックキーピング
  • 有効期限処理

パフォーマンス指標

  • 空間

データ構造で使用されるメモリ

  • 遅れ

上記のルーチンの開始と終了にかかる時間

3 ダボのタイムホイール構造

Dubbo タイマーは、dubbo-common モジュールの org.apache.dubbo.common.timer パッケージに実装されています。次に、タイマーに関係するコア インターフェースと実装を分析します。

コアインターフェース

タイマータスク

Dubbo では、スケジュールされたすべてのタスクは TimerTask インターフェイスを実装する必要があります。定義されている run() メソッドは 1 つだけであり、入力パラメーターは Timeout インターフェイス オブジェクトです。

タイムアウト

Timeout オブジェクトは、スレッド プールによって返される Future オブジェクトとスレッド プールに送信されたタスク オブジェクトの関係と同様に、TimerTask オブジェクトと 1 対 1 で対応します。
Timeout オブジェクトを使用すると、スケジュールされたタスクのステータスを表示できるだけでなく、スケジュールされたタスクを操作することもできます (たとえば、関連するスケジュールされたタスクをキャンセルするなど)。

Timeout インターフェースのメソッド:

Timer インターフェイスはタイマーの基本的な動作を定義します。その中核となるのは newTimeout() です。つまり、スレッド プールにタスクを送信するのと同様に、時間制限付きタスク (TimerTask) を送信し、関連付けられた Timeout オブジェクトを返します。

ハッシュホイールタイムアウト

HashedWheelTimeout は、Timeout インターフェイスの唯一の実装であり、HashedWheelTimer の内部クラスです。 HashedWheelTimeout には 2 つの役割があります。

タイムホイール内の双方向リンクリストのノード、つまりHashedWheelTimer内のタイマータスクTimerTaskのコンテナ

タイマー タスク TimerTask が HashedWheelTimer に送信された後に返されるハンドルは、タイム ホイールの外部でタイマー タスクを表示および制御するために使用されます。

コア分野

前へ、次へ。二重リンク リストは、HashedWheelTimerBucket でタイムアウトを連鎖するために使用されます。これは WorkerThread でのみ機能するため、同期/揮発性は必要ありません。

task 、スケジュールされている実際のタスク

期限、スケジュールされたタスクが実行される時間。 HashedWheelTimeoutを作成するときは、計算式を指定します:currentTime(HashedWheelTimeoutが作成された時刻)+ delay(タスク遅延時間)- startTime(HashedWheelTimerの開始時刻)、ns

状態、スケジュールされたタスクの現在の状態

オプションのステータス:

STATE_UPDATER は、状態変更のアトミック性を実装するために使用されます。

residualRounds : 現在のタスクに残っているクロック サイクルの数。タイム ホイールが表すことができる時間の長さには制限があります。タスクの有効期限と現在の時刻の差が、タイム ホイールの 1 回転で表すことができる時間の長さを超えると、ループが発生し、残りのクロック サイクルを表すためにこのフィールドの値が必要になります。

コアAPI

キャンセルされました()

期限切れです()

州()
現在のHashedWheelTimeoutステータスを確認する

cancel()メソッド

expire()メソッド

取り除く()

ハッシュホイールバケット

時の車輪の中の隙間。
タイム ホイールのスロットは、実際には二重リンク リストをキャッシュして管理するためのコンテナーです。二重リンク リストの各ノードは、TimerTask タイミング タスクに関連付けられた HashedWheelTimeout オブジェクトです。

HashedWheelBucket は、双方向リンク リストの最初と最後のノード (先頭と末尾) を保持します。さらに、各 HashedWheelTimeout ノードは先行参照と後続参照を保持するため、リンク リスト全体を前方および後方にトラバースできます。

コアAPI

タイムアウトを追加します。

ポーリングタイムアウト()

取り除く()
指定された HashedWheelTimeout ノードを二重リンク リストから削除します。

タイムアウトをクリアする()
pollTimeout() メソッドは周期的に呼び出され、二重リンク リスト全体を処理して、タイムアウトまたはキャンセルされていないすべてのタスクを返します。

有効期限切れ()
二重リンク リスト内のすべての HashedWheelTimeout ノードを走査します。期限切れのスケジュールされたタスクを処理する場合、そのタスクは remove() メソッドによって取り出され、expire() メソッドが呼び出されて実行されます。キャンセルされたタスクの場合は、remove() メソッドによって取り出された後、直接破棄されます。期限切れになっていないタスクの場合は、remainingRounds フィールド (残りのクロック サイクル数) が 1 つ減ります。

ハッシュホイールタイマー

タイム ホイール アルゴリズムを通じてタイマーを実装する Timer インターフェイスの実装。

機能

現在のタイムホイール ポインターに従って対応する HashedWheelBucket スロットを選択し、リンク リストの先頭から反復処理して、各 HashedWheelTimeout スケジュール タスクを計算します。

  • 現在のクロックサイクルに属する場合は、取り出されて実行されます
  • グループに属していない場合は、残りのクロック サイクル数が 1 つ減少します。

コアドメイン

ワーカーステート
タイムホイールの現在の状態。AtomicIntegerFieldUpdater によってアトミックに変更される 3 つのオプション値。

開始時間
現在のタイム ホイールの開始時刻。このタイム ホイールに送信されたスケジュールされたタスクの期限フィールド値は、このタイムスタンプに基づいて計算されます。

車輪
タイムホイールの循環キュー。各要素はスロットです。タイムスロットの数がnと指定されている場合、nに最も近い2番目の累乗値が上方に取られます。

タイムアウト、キャンセルされたタイムアウト
HashedWheelTimer は、HashedWheelBucket の双方向リンク リストを処理する前に、これら 2 つのキューのデータを処理します。

タイムアウト キュー<br /> 外部送信タイムホイールでスケジュールされたタスクをバッファリングする

キャンセルされたタイムアウト キュー<br /> キャンセルされたスケジュールされたタスクを一時的に保存する

チェック
HashedWheelTimer$Workerにある、タイムホイールのポインター。ステップサイズが1の単調に増加するカウンター。

マスク
マスク、mask = wheel.length - 1、ticksとmaskを実行して対応するクロックスロットを見つけます

ティック期間
時間ポインターの各増分によって表される実際の時間はナノ秒単位です。

保留タイムアウト
現在のタイムラウンドに残っているスケジュールされたタスクの合計数。

ワーカースレッド
実際にタイミング タスクを実行するタイム ホイール内のスレッド。

ワーカー
スケジュールされたタスクを実際に実行するロジックは、この Runnable オブジェクトにカプセル化されます。

新しいタイムアウト()

スケジュールされたタスクを送信します。スケジュールされたタスクがタイムアウト キューに入る前に、start() メソッドが呼び出されてタイム ホイールが開始され、次の 2 つの重要な手順が完了します。

  1. タイムホイールのstartTimeフィールドを決定する
  2. workerThread スレッドを開始し、ワーカー タスクの実行を開始します。

次に、スケジュールされたタスクの期限が startTime に従って計算され、最後にスケジュールされたタスクは HashedWheelTimeout にカプセル化され、タイムアウト キューに追加されます。

4 タイムホイールポインターの1回転の実行フロー

HashedWheelTimer$Worker.run():

  1. タイムホイールのポインターが回転し、タイムホイールのサイクルが始まります
  2. ユーザーによって積極的にキャンセルされたスケジュールされたタスクをクリーンアップします。これらのスケジュールされたタスクがユーザーによってキャンセルされると、cancelledTimeouts キューに記録されます。ポインタが動くたびに、タイムホイールはキューをクリアします
  3. タイムアウトキューにキャッシュされたスケジュールされたタスクをタイムホイールの対応するスロットに転送します。
  4. 現在のポインタに従って対応するスロットを見つけ、スロットの双方向リンクリスト内のスケジュールされたタスクを処理します。
  5. タイムホイールの状態を確認します。タイムホイールが実行状態にある場合、上記の手順が周期的に実行され、タイミングタスクが継続的に実行されます。タイマーが停止状態の場合、次の手順を実行して、実行されていない時間指定タスクを取得し、それらを unprocessedTimeouts キューに追加します。タイマー内の各スロットを走査して clearTimeouts() メソッドを呼び出し、タイムアウト キューに追加されていないスロットに対して poll() を周期的に呼び出します。
  6. 最後に、ユーザーによってアクティブにキャンセルされた、cancelledTimeouts キュー内のスケジュールされたタスクをクリアします。

5 スケジュールされたタスクアプリケーション

これは定期的な操作に直接使用されるのではなく、タイム ホイールにスケジュールされた単一のタスクを送信するだけです。前のタスクが完了したら、newTimeout() メソッドを呼び出して現在のタスクを再度送信し、次のサイクルでタスクが実行されるようにします。タスク実行中に GC や I/O ブロッキングなどが発生し、タスクの遅延や詰まりが発生した場合でも、同じタスクが連続して送信されることはなく、タスクが蓄積されます。

Dubbo タイムホイールの用途は主に以下の分野です。

  1. 失敗の再試行。たとえば、プロバイダーがレジストリへの登録に失敗した場合や、コンシューマーがレジストリへのサブスクライブに失敗した場合などに再試行します。
  2. 定期的にスケジュールされたタスク(ハートビート要求を定期的に送信する、要求のタイムアウトを処理する、ネットワーク接続が切断された後に再接続するなど)

参照する

https://zhuanlan.zhihu.com/p/32906730

<<:  ノーコード プラットフォーム トップ 8: 2020 年に見逃せない機械学習プラットフォーム

>>:  アリババが国際AIサミットを主催、医療AIとマルチメディアコンテンツ理解が話題に

ブログ    
ブログ    
ブログ    

推薦する

ChatGPTに対抗できるAIモデル6つと中国企業の製品2つが選定

ChatGPT は、大規模言語モデル (LLM) に基づく業界をリードするチャットボットとして、テク...

Kingsoft Cloudは、スマートシティ構築のパートナーとなり、人間中心のスマートシティエコシステムを構築することを目指しています。

スマートシティはデジタル中国とスマート社会の中核を担うものとして国家戦略のレベルにまで高まり、現在中...

クラウド AI とエッジ AI: 2022 年にはどちらがより良い選択でしょうか?

エッジ AI とクラウド AI は、現在企業が使用している最も重要なテクノロジーの一部であることがわ...

...

AIチップの過去と未来、この記事を読んでください

[[248236]]皆さんは、イ・セドルと柯潔を破った Google の「Alpha Go」をまだ覚...

AIとデータ分析を活用してデータを収益化する4つの手法

ビジネスにとってのデータの経済的価値を概念化したり直接測定したりすることは困難です。多くの経営者は、...

機械学習、データサイエンス、人工知能、ディープラーニング、統計などの違い。

データ サイエンスは幅広い分野であるため、まずはあらゆるビジネスで遭遇する可能性のあるデータ サイエ...

PyTorch と NumPy の徹底比較! ! !

こんにちは、Xiaozhuangです! pytorch のコンテンツを更新するように多くの人から促さ...

...

AIが医薬品開発において適切な医薬品成分の特定にどのように役立つか

[[378110]]デジタル技術の導入に関しては、製薬業界では導入が遅れる傾向にあります。これまで、...

教育におけるAIの想像力と限界

広東省の有名な重点中学校である広亜中学校は最近、電子ブレスレット3,500個を購入するために485万...

Nvidiaの次世代GPUが発表、H100を超える!最初の3nmマルチチップモジュール設計は2024年にデビュー予定

3nmプロセス、H100をはるかに超える性能!つい最近、海外メディアのDigiTimesが、コードネ...

機械学習は、足を上げることから敷居に落ちることまで行います

突然、AI 時代に入ったようです。裏では、多くの友人が、来たる All in AI を迎えるために、...

AI リサーチ インスティテュートが 2021 年の AI 技術トレンド トップ 10 を発表

[[374480]] 12月31日、AI研究所は2020年のAIの進歩トップ10を発表しました。新年...

テキスト生成画像は非常に人気があり、これらの技術の進化を理解する必要があります

OpenAIは最近、AIコミュニティに「地震」を引き起こしたDALL・E 2システムをリリースしま...