yuzd / Hangfire.HttpJob

httpjob for Hangfire,restful api for Hangfire,job调度与业务分离
https://github.com/yuzd/Hangfire.HttpJob/wiki
MIT License
630 stars 186 forks source link

使用中发现表hangfireset中id总是大幅度自增如何解决? #179

Closed lixingyuabc closed 1 year ago

lixingyuabc commented 1 year ago

数据库中设置的默认自增步长是100,其它表中数据都正常,就这张表中自增的比较恐怖,20个作业通过面板连续修改作业配置数百十次最大的ID就已经扩张到了7-8位数了,这个修改存储的机制是不是哪里需要改善下配置?版本:1.7.28

yuzd commented 1 year ago

我看看

yuzd commented 1 year ago

VGD()}IBX6I7JDK@AYOVRUJ

hangfire的调度器 在不停的 update job的这个score(目的是把这个job的下一次调度时间给更新进去)

所以会频繁调用storage的AddToSet

而mysql的这个实现

image

采用了

INSERT INTO `hangfireSet` (`Key`, `Value`, `Score`) VALUES (@Key, @Value, @Score) ON DUPLICATE KEY UPDATE `Score` = @Score 

会导致表的主键跳跃的厉害

S%@OG`)$C_2HFPZ%B6X4E`2

HN F6PQV(_40$FXMID}ADKJ

修改mysqlstorage工程的源码 https://github.com/arnoldasgudas/Hangfire.MySqlStorage/blob/master/Hangfire.MySql/MySqlWriteOnlyTransaction.cs

 public override void AddToSet(string key, string value, double score)
        {
            Logger.TraceFormat("AddToSet key={0} value={1}", key, value);

            AcquireSetLock();
            QueueCommand(x =>
            {
                var sql = "";
                if (key == "recurring-jobs") // 只发现这个key存在这个问题
                {
                     // key+value是uniq 改成先update 如果没有成功 再insert
                    sql = $"UPDATE `{_storageOptions.TablesPrefix}Set` set `Score` = @score where `Key` = @key and `Value` = @value";
                    var updateRt = x.Execute(sql, new { score = score, key = key, value = value });
                    if (updateRt < 1)
                    {
                        sql = $"INSERT INTO `{_storageOptions.TablesPrefix}Set` (`Key`, `Value`, `Score`) " +
                              "VALUES (@Key, @Value, @Score) ";
                        x.Execute(
                            sql,
                            new { key, value, score });
                    }
                }
                else
                {
                    sql = $"INSERT INTO `{_storageOptions.TablesPrefix}Set` (`Key`, `Value`, `Score`) " +
                          "VALUES (@Key, @Value, @Score) " +
                          "ON DUPLICATE KEY UPDATE `Score` = @Score";
                   x.Execute(
                       sql,
                       new { key, value, score });
                }

                //Console.WriteLine(sql + " ==> " + key + "@" + value + "@" + score);
            });
        }

https://github.com/arnoldasgudas/Hangfire.MySqlStorage/pull/97

yuzd commented 1 year ago

我发现换成用 https://github.com/MiloszKrajewski/Hangfire.Storage.MySql 这个版本的mysqlstorage没有这个问题 建议mysql用这个