時間輪算法定時器 antlabs-timer 介紹

推薦理由

當業務要處理大量的定時任務時,如果每個任務都創建一個 Golang 原生的 timer 的話,會佔用較多的 cpu 資源,這類場景,可以用時間輪算法優化 timer 的資源消耗。本次介紹一款多級時間輪庫 antlabs/timer(以下 timer 特指 antlabs/timer 庫),處理類似場景的優化。

功能介紹

timer 最小的時間粒度是 10ms, antlabs/timer 支持以下功能:

  1. 一次性定時,類似 time.AfterFunc;

  2. 週期性執行,類似 time.Ticker;

  3. 取消單個任務;

  4. 停止所有任務。

使用指南

安裝

go get github.com/antlabs/timer

代碼示例

下面是一個簡單的例子:

package main

import (
 "log"
 "time"

 "github.com/antlabs/timer"
)

func main() {
 tm := timer.NewTimer()

 // 一次性執行,2s後執行
 tm.AfterFunc(2*time.Second, func() {
  log.Printf("2 time.Second")
 })

 // tk3 會被 tk3.Stop()函數調用取消掉
 tk3 := tm.AfterFunc(3*time.Second, func() {
  log.Printf("3 time.Second")
 })

 tk3.Stop() //取消tk3

 // 週期執行,每1s執行一次
 tm.ScheduleFunc(1*time.Second, func() {
  log.Printf("schedule\n")
 })

 tm.Run()

}

timer 使用起來是比較簡單的,根據業務場景選擇合適的接口就好。

benchmark

Golang 1.14 對定時器做了優化,每個 P 維護一個定時器,減少了添加刪除任務時的鎖競爭,但是和本文介紹的 timer 庫對比起來還是有些耗資源,下面是 benchmark 的結果:

Golang 版本:1.16.6

cpu: Intel(R) Core(TM) i5-8257U CPU @ 1.40GHz
Benchmark_antlabs_Timer_AddTimer
Benchmark_antlabs_Timer_AddTimer/N-1m
Benchmark_antlabs_Timer_AddTimer/N-1m-8         9226951        116.6 ns/op       80 B/op        1 allocs/op
Benchmark_antlabs_Timer_AddTimer/N-5m
Benchmark_antlabs_Timer_AddTimer/N-5m-8         9589074        153.9 ns/op       80 B/op        1 allocs/op
Benchmark_antlabs_Timer_AddTimer/N-10m
Benchmark_antlabs_Timer_AddTimer/N-10m-8        9621186        167.0 ns/op       80 B/op        1 allocs/op
Benchmark_Stdlib_AddTimer
Benchmark_Stdlib_AddTimer/N-1m
Benchmark_Stdlib_AddTimer/N-1m-8                4967716        220.0 ns/op       81 B/op        1 allocs/op
Benchmark_Stdlib_AddTimer/N-5m
Benchmark_Stdlib_AddTimer/N-5m-8                5265825        237.9 ns/op       80 B/op        1 allocs/op
Benchmark_Stdlib_AddTimer/N-10m
Benchmark_Stdlib_AddTimer/N-10m-8               7703940        230.8 ns/op       80 B/op        1 allocs/op

總結

timer 利用時間輪算法,通過降低定時器精度的方式,將同一個時間單位內的任務集中存儲到一個雙向鏈表,可以一次鎖操作處理,減少鎖競爭,進而提高性能,對於業務中有大量定時任務,同時對精度要求大於 10ms 的場景,可以嘗試 timer 庫來優化。

參考資料

  1. https://github.com/antlabs/timer

  2. https://spongecaptain.cool/post/widget/timingwheel/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/emNifkcdn9oRjVHRcQmK9w