mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2026-01-07 00:05:49 +08:00
调整空闲时间清理缓存算法
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"github.com/shirou/gopsutil/v3/load"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -1025,8 +1026,15 @@ func (this *FileStorage) purgeLoop() {
|
||||
var times = 1
|
||||
|
||||
// 空闲时间多清理
|
||||
if utils.SharedFreeHoursManager.IsFreeHour() {
|
||||
times = 5
|
||||
systemLoad, _ := load.Avg()
|
||||
if systemLoad != nil {
|
||||
if systemLoad.Load5 < 2 {
|
||||
times = 5
|
||||
} else if systemLoad.Load5 < 3 {
|
||||
times = 3
|
||||
} else if systemLoad.Load5 < 5 {
|
||||
times = 2
|
||||
}
|
||||
}
|
||||
|
||||
// 处于LFU阈值时,多清理
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/goman"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
var SharedFreeHoursManager = NewFreeHoursManager()
|
||||
|
||||
func init() {
|
||||
if !teaconst.IsMain {
|
||||
return
|
||||
}
|
||||
|
||||
events.On(events.EventLoaded, func() {
|
||||
goman.New(func() {
|
||||
SharedFreeHoursManager.Start()
|
||||
})
|
||||
})
|
||||
events.OnClose(func() {
|
||||
SharedFreeHoursManager.Stop()
|
||||
})
|
||||
}
|
||||
|
||||
// FreeHoursManager 计算节点空闲时间
|
||||
// 以便于我们在空闲时间执行高强度的任务,如清理缓存等
|
||||
type FreeHoursManager struct {
|
||||
dayTrafficMap map[int][24]uint64 // day => [ traffic bytes ]
|
||||
lastBytes uint64
|
||||
|
||||
freeHours []int
|
||||
count int
|
||||
|
||||
locker sync.Mutex
|
||||
ticker *time.Ticker
|
||||
}
|
||||
|
||||
func NewFreeHoursManager() *FreeHoursManager {
|
||||
return &FreeHoursManager{dayTrafficMap: map[int][24]uint64{}, count: 3}
|
||||
}
|
||||
|
||||
func (this *FreeHoursManager) Start() {
|
||||
this.ticker = time.NewTicker(30 * time.Minute)
|
||||
for range this.ticker.C {
|
||||
this.Update(atomic.LoadUint64(&teaconst.InTrafficBytes))
|
||||
}
|
||||
}
|
||||
|
||||
func (this *FreeHoursManager) Update(bytes uint64) {
|
||||
if this.count <= 0 {
|
||||
this.count = 3
|
||||
}
|
||||
|
||||
if this.lastBytes == 0 {
|
||||
this.lastBytes = bytes
|
||||
} else {
|
||||
// 记录流量
|
||||
var deltaBytes = bytes - this.lastBytes
|
||||
var now = time.Now()
|
||||
var day = now.Day()
|
||||
var hour = now.Hour()
|
||||
traffic, ok := this.dayTrafficMap[day]
|
||||
if ok {
|
||||
traffic[hour] += deltaBytes
|
||||
} else {
|
||||
var traffic = [24]uint64{}
|
||||
traffic[hour] += deltaBytes
|
||||
this.dayTrafficMap[day] = traffic
|
||||
}
|
||||
|
||||
this.lastBytes = bytes
|
||||
|
||||
// 计算空闲时间
|
||||
var result = [24]uint64{}
|
||||
var hasData = false
|
||||
for trafficDay, trafficArray := range this.dayTrafficMap {
|
||||
// 当天的不算
|
||||
if trafficDay == day {
|
||||
continue
|
||||
}
|
||||
|
||||
// 查看最近5天的
|
||||
if (day > trafficDay && day-trafficDay <= 5) || (day < trafficDay && trafficDay-day >= 26) {
|
||||
var weights = this.sortUintArrayWeights(trafficArray)
|
||||
for k, v := range weights {
|
||||
result[k] += v
|
||||
}
|
||||
hasData = true
|
||||
}
|
||||
}
|
||||
if hasData {
|
||||
var freeHours = this.sortUintArrayIndexes(result)
|
||||
this.locker.Lock()
|
||||
this.freeHours = freeHours[:this.count] // 取前N个小时作为空闲时间
|
||||
this.locker.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *FreeHoursManager) IsFreeHour() bool {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
if len(this.freeHours) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var hour = time.Now().Hour()
|
||||
for _, h := range this.freeHours {
|
||||
if h == hour {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *FreeHoursManager) Stop() {
|
||||
if this.ticker != nil {
|
||||
this.ticker.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
// 对数组进行排序,并返回权重
|
||||
func (this *FreeHoursManager) sortUintArrayWeights(arr [24]uint64) [24]uint64 {
|
||||
var l = []map[string]interface{}{}
|
||||
for k, v := range arr {
|
||||
l = append(l, map[string]interface{}{
|
||||
"k": k,
|
||||
"v": v,
|
||||
})
|
||||
}
|
||||
sort.Slice(l, func(i, j int) bool {
|
||||
var m1 = l[i]
|
||||
var v1 = m1["v"].(uint64)
|
||||
|
||||
var m2 = l[j]
|
||||
var v2 = m2["v"].(uint64)
|
||||
|
||||
return v1 < v2
|
||||
})
|
||||
|
||||
var result = [24]uint64{}
|
||||
for k, v := range l {
|
||||
if k < this.count {
|
||||
k = 0
|
||||
} else {
|
||||
k = 1
|
||||
}
|
||||
result[v["k"].(int)] = v["v"].(uint64)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// 对数组进行排序,并返回索引
|
||||
func (this *FreeHoursManager) sortUintArrayIndexes(arr [24]uint64) [24]int {
|
||||
var l = []map[string]interface{}{}
|
||||
for k, v := range arr {
|
||||
l = append(l, map[string]interface{}{
|
||||
"k": k,
|
||||
"v": v,
|
||||
})
|
||||
}
|
||||
sort.Slice(l, func(i, j int) bool {
|
||||
var m1 = l[i]
|
||||
var v1 = m1["v"].(uint64)
|
||||
|
||||
var m2 = l[j]
|
||||
var v2 = m2["v"].(uint64)
|
||||
|
||||
return v1 < v2
|
||||
})
|
||||
|
||||
var result = [24]int{}
|
||||
var i = 0
|
||||
for _, v := range l {
|
||||
result[i] = v["k"].(int)
|
||||
i++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestFreeHoursManager_Update(t *testing.T) {
|
||||
var manager = NewFreeHoursManager()
|
||||
manager.Update(111)
|
||||
|
||||
manager.dayTrafficMap[1] = [24]uint64{1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1}
|
||||
manager.dayTrafficMap[2] = [24]uint64{0, 0, 1, 0, 1, 1, 1, 0, 0}
|
||||
manager.dayTrafficMap[3] = [24]uint64{0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1}
|
||||
manager.dayTrafficMap[4] = [24]uint64{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
|
||||
manager.dayTrafficMap[5] = [24]uint64{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
|
||||
manager.dayTrafficMap[6] = [24]uint64{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1}
|
||||
manager.dayTrafficMap[7] = [24]uint64{}
|
||||
manager.dayTrafficMap[8] = [24]uint64{}
|
||||
manager.dayTrafficMap[9] = [24]uint64{}
|
||||
manager.dayTrafficMap[10] = [24]uint64{1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
|
||||
manager.dayTrafficMap[11] = [24]uint64{1}
|
||||
manager.dayTrafficMap[12] = [24]uint64{1}
|
||||
manager.dayTrafficMap[13] = [24]uint64{1}
|
||||
manager.dayTrafficMap[14] = [24]uint64{}
|
||||
manager.dayTrafficMap[15] = [24]uint64{}
|
||||
manager.dayTrafficMap[16] = [24]uint64{}
|
||||
manager.dayTrafficMap[25] = [24]uint64{}
|
||||
manager.dayTrafficMap[26] = [24]uint64{}
|
||||
manager.dayTrafficMap[27] = [24]uint64{}
|
||||
manager.dayTrafficMap[28] = [24]uint64{}
|
||||
manager.dayTrafficMap[29] = [24]uint64{}
|
||||
manager.dayTrafficMap[30] = [24]uint64{}
|
||||
manager.dayTrafficMap[31] = [24]uint64{}
|
||||
|
||||
var before = time.Now()
|
||||
manager.Update(222)
|
||||
t.Log(manager.freeHours)
|
||||
t.Log(manager.IsFreeHour())
|
||||
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||
}
|
||||
|
||||
func TestFreeHoursManager_SortArray(t *testing.T) {
|
||||
var manager = NewFreeHoursManager()
|
||||
t.Log(manager.sortUintArrayWeights([24]uint64{0, 1, 2, 3, 4, 5, 6, 7, 8, 109, 10, 11, 12, 130, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}))
|
||||
t.Log(manager.sortUintArrayIndexes([24]uint64{1, 2, 3, 5, 4, 0, 100}))
|
||||
}
|
||||
Reference in New Issue
Block a user