1 スケジュールされたタスク Netty、Quartz、Kafka、Linux にはすべてスケジュールされたタスク機能があります。 JDK に付属する java.util.Timer と DelayedQueue は、単純なスケジュールされたタスクを実装できます。基礎となるレイヤーはヒープを使用し、アクセスの複雑さは O(nlog(n)) ですが、大規模なスケジュールされたタスクをサポートすることはできません。 タスク量が多く、パフォーマンス要件が高いシナリオでは、タイムホイールアルゴリズムを使用して、タスクアクセスとキャンセル操作の時間計算量を O(1) に削減します。 2 タイムホイールモデルとその応用 スケジュールされたタスクを効率的にバッチ管理するためのスケジューリング モデル。これは通常、時計に似たリング構造として実装され、多くのスロットに分割され、1 つのスロットは時間間隔を表し、各スロットは双方向リンク リストを使用してスケジュールされたタスクを格納します。 ポインタは定期的にジャンプし、スロットにジャンプすると、そのスロットのタイミング タスクが実行されます。 ハッシュタイミングホイール構造図
タイマーの維持には費用がかかる
全体的な割り込みオーバーヘッドを削減するには、効率的なタイマー アルゴリズムが必要です。 単層タイムホイールの容量と精度には限界があります。特に高い精度が求められるシナリオ、特に長い時間範囲、またはスケジュールする必要のある大量のタスクがある場合、通常は、マルチレベル タイムホイールと、永続ストレージとタイムホイールを組み合わせたソリューションが使用されます。 モデルとパフォーマンスの指標 モデルのルール クライアントからの呼び出し:
タイマーティック呼び出し:
パフォーマンス指標
データ構造で使用されるメモリ
上記のルーチンの開始と終了にかかる時間 3 ダボのタイムホイール構造 Dubbo タイマーは、dubbo-common モジュールの org.apache.dubbo.common.timer パッケージに実装されています。次に、タイマーに関係するコア インターフェースと実装を分析します。 コアインターフェース タイマータスク Dubbo では、スケジュールされたすべてのタスクは TimerTask インターフェイスを実装する必要があります。定義されている run() メソッドは 1 つだけであり、入力パラメーターは Timeout インターフェイス オブジェクトです。 タイムアウト Timeout オブジェクトは、スレッド プールによって返される Future オブジェクトとスレッド プールに送信されたタスク オブジェクトの関係と同様に、TimerTask オブジェクトと 1 対 1 で対応します。 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 キャンセルされました() 期限切れです() 州() cancel()メソッド expire()メソッド 取り除く() ハッシュホイールバケット 時の車輪の中の隙間。 HashedWheelBucket は、双方向リンク リストの最初と最後のノード (先頭と末尾) を保持します。さらに、各 HashedWheelTimeout ノードは先行参照と後続参照を保持するため、リンク リスト全体を前方および後方にトラバースできます。 コアAPI タイムアウトを追加します。 ポーリングタイムアウト() 取り除く() タイムアウトをクリアする() 有効期限切れ() ハッシュホイールタイマー タイム ホイール アルゴリズムを通じてタイマーを実装する Timer インターフェイスの実装。 機能 現在のタイムホイール ポインターに従って対応する HashedWheelBucket スロットを選択し、リンク リストの先頭から反復処理して、各 HashedWheelTimeout スケジュール タスクを計算します。
コアドメイン ワーカーステート 開始時間 車輪 タイムアウト、キャンセルされたタイムアウト タイムアウト キュー<br /> 外部送信タイムホイールでスケジュールされたタスクをバッファリングする キャンセルされたタイムアウト キュー<br /> キャンセルされたスケジュールされたタスクを一時的に保存する チェック マスク ティック期間 保留タイムアウト ワーカースレッド ワーカー 新しいタイムアウト() スケジュールされたタスクを送信します。スケジュールされたタスクがタイムアウト キューに入る前に、start() メソッドが呼び出されてタイム ホイールが開始され、次の 2 つの重要な手順が完了します。
次に、スケジュールされたタスクの期限が startTime に従って計算され、最後にスケジュールされたタスクは HashedWheelTimeout にカプセル化され、タイムアウト キューに追加されます。 4 タイムホイールポインターの1回転の実行フロー HashedWheelTimer$Worker.run():
5 スケジュールされたタスクアプリケーション これは定期的な操作に直接使用されるのではなく、タイム ホイールにスケジュールされた単一のタスクを送信するだけです。前のタスクが完了したら、newTimeout() メソッドを呼び出して現在のタスクを再度送信し、次のサイクルでタスクが実行されるようにします。タスク実行中に GC や I/O ブロッキングなどが発生し、タスクの遅延や詰まりが発生した場合でも、同じタスクが連続して送信されることはなく、タスクが蓄積されます。 Dubbo タイムホイールの用途は主に以下の分野です。
参照する https://zhuanlan.zhihu.com/p/32906730 |
<<: ノーコード プラットフォーム トップ 8: 2020 年に見逃せない機械学習プラットフォーム
>>: アリババが国際AIサミットを主催、医療AIとマルチメディアコンテンツ理解が話題に
大規模モデルの時代において、Transformer は科学研究分野全体を一手にサポートします。 Tr...
OpenAI はおそらく歴史上最も困難な AI 著作権訴訟に直面している。原告のニューヨーク・タイ...
[51CTO.com クイック翻訳] 機械学習の分野を見ると、ソフトウェアエンジニアリングの原理を...
ディープラーニングはコンピュータービジョンや自然言語処理などの分野でますます大きな成果を上げており、...
[[422829]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...
7月9日から7月11日まで、2020年世界人工知能会議クラウドサミットが上海で閉幕しました。「イン...
グラフ埋め込み、グラフ表現、グラフ分類、グラフニューラルネットワーク、この記事では必要なグラフモデリ...
[[327815]]この記事を読むと、次のことがわかります。 1. シーケンス予測問題のための単純な...
[[253255]] 1. 2018 年の世界の AI 業界の発展は非常に爆発的でした。...
著者: Yajie Yingliang、Chen Long 他導入美団のフードデリバリー事業が成長を...