当高并发情况下,对某一个表的同一条数据进行更新操作时,如果每次都是更新同一个数据的话会性能比较低下,大概并发只能到300-400之间,所以需要对数据叠加定时进行更新操作,golang可以使用时间轮进行定时获取redis里存储的数据,然后定时将数据更新到表中,虽然redis是单线程的,但是高并发情况下,不要直接使用set和del等操作,这样会导致有些统计的数据丢失,进行使用inc等方法操作,这样可以保证redis中的数据一致,改用此方法后每秒只是更新一次数据库,并发大概为5000-6000之前。具体代码如下

tw := timewheel.New(time.Second, 60)
tw.Start()
key := "scoreUpdate"
//添加定时任务
//参数:interval 时间间隔
//参数:times 执行次数 -1 表示周期任务 >0 执行指定次数
//参数:key 任务唯一标识符 用户更新任务和删除任务
//参数:taskData 回调函数参数
//参数:job 回调函数
err := tw.AddTask(time.Second, -1, key, timewheel.TaskData{},
    func(params timewheel.TaskData) {
        var scoreKey = "test"
        var mapObj = make(map[string]string)
        mapObj, err := cache.Cache.HGetAllMap(scoreKey)
        if err != nil {
            helper.Error("更新错误", err.Error())
            return
        }

        for k, v := range mapObj {
            var count, _ = strconv.Atoi(v)
            cache.Cache.HINCRBY(scoreKey, k, -count)

            err := dao.GetDB().Model(model.Users{}).Where("id=?", k).
                Update("score", gorm.Expr("score+ ?", count)).Error

            if err != nil {
                helper.Error("更新错误", err.Error())
                return
            }
        }
    })

if err != nil {
    helper.Error("定时器错误", err)
}
最后修改:2022 年 09 月 18 日 04 : 12 PM
如果觉得我的文章对你有用,请随意赞赏