時間輪這個東西,這個東西並不是為mmo所設計的。它的由來也就是為了優化傳統的定時器效率低下的問題。
在開發高效能伺服器中,定時器總是不可或缺的
傳統的定時器實現思想。 分兩種
1.最low的一種, 只有乙個定時器。 需要遍歷所有的定時任務。時間複雜度o(n).
2.比較科學的一種,使用乙個最小堆的資料結構(優先佇列),來構建整個定時任務的結構。開啟乙個定時任務複雜度為o(logn);
時間輪先上個圖:
時間輪演算法可以通過上圖來描述。假設時間**小為 8,1s 轉一格,每格指向乙個鍊錶,儲存著待執行的任務。
假設,當前位於 2,現在要新增乙個 3s 後指向的任務,則 2+3=5,在第 5 格的鍊錶中新增乙個節點指向任務即可,標識 round=0。
假設,當前位於 2,現在要新增乙個 10s 後指向的任務,則(2+10)% 8 = 4,則在第 4 格新增乙個節點指向任務,並標識 round=1,則當時間輪第二次經過第 4 格時,即會執行任務。
時間輪只會執行 round=0 的任務,並會把該格仔上的其他任務的 round 減 1。
時間輪可以做新加入乙個定時任務,刪除乙個定時任務,執行乙個到期任務複雜度都為o(1).
時間輪有分為兩種, 一種為簡單時間輪, 一種為分極時間輪。
簡單時間輪, 就是上面所述的那種。
分級時間輪: 類似於水表,當小輪子裡的指標轉動滿一圈後,上一級輪子的指標進一格。 採用五個輪子每個輪子為乙個簡單時間輪,大小分別為 2^8, 2^6, 2^6, 2^6, 26,所需空間:28 + 2^6 + 2^6 + 2^6 + 2^6 = 512, 可表示的範圍為 0 – 2^8 * 2^6 * 2^6* 2^6* 2^6 = 2^32。
上圖:分級時間輪
分層時間輪是這樣一種思想:
針對時間複雜度的問題:不做遍歷計算round,凡是任務列表中的都應該是應該被執行的,直接全部取出來執行。
針對空間複雜度的問題:分層,每個時間粒度對應乙個時間輪,多個時間輪之間進行級聯協作。
第一點很好理解,第二點有必要舉個例子來說明,比如我有三個任務:
任務一每週二上午九點。
任務二每週四上午九點。
任務三每個月12號上午九點。
三個任務涉及到四個時間單位:小時、天、星期、月份。
拿任務三來說,任務三得到執行的前提是,時間刻度先得來到12號這一天,然後才需要關注其更細一級的時間單位:上午9點。
基於這個思想,我們可以設定三個時間輪:月輪、周輪、天輪。
月輪的時間刻度是天。
周輪的時間刻度是天。
天輪的時間刻度是小時。
初始新增任務時,任務一新增到天輪上,任務二新增到周輪上,任務三新增到月輪上。
三個時間輪以各自的時間刻度不停流轉。
當周輪移動到刻度2(星期二)時,取出這個刻度下的任務,丟到天輪上,天輪接管該任務,到9點執行。
同理,當月輪移動到刻度12(12號)時,取出這個刻度下的任務,丟到天輪上,天輪接管該任務,到9點執行。
這樣就可以做到既不浪費空間,有不浪費時間。
至於採用round型(簡單時間輪)的時間輪還是採用分層時間輪,看實際需要吧,時間複雜度和實現複雜度的取捨
幾種常用定時器演算法時間複雜度對比:
簡單說說Kafka中的時間輪演算法
簡單說說時間輪吧,它是乙個高效的延時佇列,或者說定時器。實際上現在網上對於時間輪演算法的解釋很多,定義也很全,這裡引用一下朱小廝部落格裡出現的定義 參考下圖,kafka中的時間輪 timingwheel 是乙個儲存定時任務的環形佇列,底層採用陣列實現,陣列中的每個元素可以存放乙個定時任務列表 tim...
kafka中對時間輪的應用分析
kafka中存在著大量的延時操作,比如延遲生產,延遲拉取,延遲刪除等,這些延時操作並不是基於jdk 自帶的timer或者delayqueue 實現,而是基於時間輪的概念自己實現了乙個延時定時器,jdk中timer和delayqueue的插入和刪除操作的平均時間複雜度為o nlogn 並不能滿足kaf...
基於時間輪的定時器
目錄 是乙個單層時間輪,當指標走到某一格上,就獲取那一格上掛的任務將其執行。當時如果時間跨度大的時候,格仔數明顯不夠,那麼就可以做成多級時間輪。其實就是當低層的時間輪走了一圈,將它高一層的時間輪走一格,並且將掛在高層時間輪上的任務分配下來。檔案 include timewheel.h include...