【问题标题】:Is it correct that systemd timer AccuracySec parameter make the ticks slip?systemd timer AccuracySec 参数使滴答声滑动是否正确?
【发布时间】:2017-03-29 02:20:22
【问题描述】:

我有一个悲哀的印象,计时器的滴答声正在滑倒AccuracySec

我习惯了 CRON,并且使用诸如“*/5 * * * ...”之类的内容,它将每 5 分钟运行一次(尽管如果仍在运行,它不会重新启动进程,这正是我所需要的。)

CRON 计划可以定义为:

...--|-----|-----|--...--->
    :05   :10   :15

现在我将其转换为systemd,文件如下所示:

[Unit]
Description=Run the snapbackend service once every 5 minutes.

[Timer]
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target

所以我还是想每 5 分钟打一次。

但是,他们有这个名为 AccuracySec 的参数,默认设置为 1 分钟。如您所见,我没有设置它,因为它说:

这样做是为了优化功耗以抑制不必要的 CPU 唤醒。

但看起来他们同步定时器在一起,而不是准时开始新任务。不仅如此,它的实现方式,AccuracySec 似乎是累积的。看起来会发生这种情况:

...--|-----+-|-----+-|-----+-|--...
    :05     :11     :17     :23

+代表定时器超时时间,|代表定时服务执行时间。

在我看来,1 分钟的延迟意味着下一个计时器将“迟到”2 分钟,而不仅仅是一个。如我的时间表所示,对于systemd 计时器,滴答声发生在:05、:11、:17、:23。我所期待的是::05、:10、:15、:20,等等......(请注意,如果第一个滴答声在 :05 命中,那么计时器被安排为 :04 并等待 1 分钟不醒来CPU 太快了。然后它会在 :09 计算下一个刻度,但只在 :10 执行它,等等)

我是否正确,计时器正在滑动?

【问题讨论】:

    标签: timer cron systemd


    【解决方案1】:

    快速回答:是的。它滑倒了。 (注意:这是在 Ubuntu 16.04 中,可能会在更高版本的 systemd 中修复...)

    测试

    按照@MarkStosberghis answer中的建议,我创建了一个没有Accuracy变量的计时器,以便使用默认的1分钟,然后添加变量以1秒测试,看看我的时间是否会滑倒。

    我为测试设置的 3 个文件

    snaptest.timer

    首先我创建了一个名为snaptest.timer 的文件,没有AccuracySec 参数:

    [Unit]
    Description=Test the slipping timer...
    [Timer]
    OnUnitActiveSec=5min
    [Install]
    WantedBy=timers.target
    

    对于第二个测试,我添加了AccuracySec 参数并将其设置为1(表示1秒):

    [Unit]
    Description=Test the slipping timer...
    [Timer]
    OnUnitActiveSec=5min
    AccuracySec=1           <-- added this for 2nd test
    [Install]
    WantedBy=timers.target
    

    snaptest.service

    其次我创建了一个名为snaptest.service的文件:

    [Unit]
    Description=Test slipage by logging messages
    [Service]
    Type=simple
    ExecStart=/usr/bin/snaptest
    [Install]
    WantedBy=multi-user.target
    

    /usr/bin/snaptest

    第三,我创建了一个名为/usr/bin/snaptest的脚本:

    #!/bin/sh
    echo `date` >>/var/log/snapwebsites/snaptest.log
    

    一个非常简单的脚本确实给了我一个名为 snaptest.log 的文件。

    启动定时器

    对于那些不知道的人,要启动计时器,你只需要像这样启动:

    systemctl start snaptest.timer
    

    在这种情况下,您必须指定“.timer”。

    此外,这还不够,因为snaptest.service 从未运行过,并且除非服务至少运行一次,否则计时器不会启动。所以第一次运行需要踢:

    systemctl start snaptest
    

    测试结果

    第一组以默认的 1 分钟精度呈现结果:

    Mon Aug 29 14:34:07 PDT 2016
    Mon Aug 29 14:39:09 PDT 2016
    Mon Aug 29 14:44:37 PDT 2016
    Mon Aug 29 14:50:09 PDT 2016
    Mon Aug 29 14:56:09 PDT 2016
    Mon Aug 29 15:02:09 PDT 2016
    Mon Aug 29 15:08:09 PDT 2016
    Mon Aug 29 15:14:09 PDT 2016
    Mon Aug 29 15:20:09 PDT 2016
    Mon Aug 29 15:26:09 PDT 2016
    Mon Aug 29 15:32:09 PDT 2016
    Mon Aug 29 15:38:09 PDT 2016
    Mon Aug 29 15:44:09 PDT 2016
    Mon Aug 29 15:50:09 PDT 2016
    Mon Aug 29 15:56:09 PDT 2016
    Mon Aug 29 16:02:09 PDT 2016
    Mon Aug 29 16:08:09 PDT 2016
    Mon Aug 29 16:14:09 PDT 2016
    Mon Aug 29 16:20:09 PDT 2016
    Mon Aug 29 16:26:09 PDT 2016
    Mon Aug 29 16:32:09 PDT 2016
    Mon Aug 29 16:38:09 PDT 2016
    Mon Aug 29 16:44:09 PDT 2016
    Mon Aug 29 16:50:09 PDT 2016
    Mon Aug 29 16:56:09 PDT 2016
    Mon Aug 29 17:02:09 PDT 2016
    Mon Aug 29 17:08:09 PDT 2016
    Mon Aug 29 17:14:09 PDT 2016
    

    第二组结果显示精度为1秒的结果:

    Mon Aug 29 17:19:57 PDT 2016
    Mon Aug 29 17:24:57 PDT 2016
    Mon Aug 29 17:29:58 PDT 2016
    Mon Aug 29 17:34:59 PDT 2016
    Mon Aug 29 17:40:00 PDT 2016
    Mon Aug 29 17:45:01 PDT 2016
    Mon Aug 29 17:50:02 PDT 2016
    Mon Aug 29 17:55:03 PDT 2016
    Mon Aug 29 18:00:04 PDT 2016
    Mon Aug 29 18:05:05 PDT 2016
    Mon Aug 29 18:10:06 PDT 2016
    Mon Aug 29 18:15:07 PDT 2016
    Mon Aug 29 18:20:08 PDT 2016
    Mon Aug 29 18:25:09 PDT 2016
    Mon Aug 29 18:30:10 PDT 2016
    Mon Aug 29 18:35:11 PDT 2016
    Mon Aug 29 18:40:12 PDT 2016
    Mon Aug 29 18:45:13 PDT 2016
    Mon Aug 29 18:50:14 PDT 2016
    Mon Aug 29 18:55:15 PDT 2016
    Mon Aug 29 19:00:16 PDT 2016
    Mon Aug 29 19:05:17 PDT 2016
    Mon Aug 29 19:10:18 PDT 2016
    Mon Aug 29 19:15:19 PDT 2016
    Mon Aug 29 19:20:20 PDT 2016
    Mon Aug 29 19:25:21 PDT 2016
    Mon Aug 29 19:30:22 PDT 2016
    Mon Aug 29 19:35:23 PDT 2016
    Mon Aug 29 19:40:24 PDT 2016
    Mon Aug 29 19:45:25 PDT 2016
    Mon Aug 29 19:50:26 PDT 2016
    Mon Aug 29 19:55:27 PDT 2016
    Mon Aug 29 20:00:28 PDT 2016
    Mon Aug 29 20:05:29 PDT 2016
    Mon Aug 29 20:10:30 PDT 2016
    Mon Aug 29 20:15:31 PDT 2016
    

    我对这些结果的看法

    很明显,它会滑倒... 时间窗口在 0 和 AccuracySec 之间变化。

    我想如果我想避免滑点,我必须改用OnCalendar 选项。

    【讨论】:

    • 您的测试是为了获得最大准确度,使用“1 秒”作为准确度。文档和我的回答中推荐的是“1us”,这是最大精度。我建议用它重新运行你的测试。如果仍然滑倒,请报告错误。
    • 虽然,您的“每 5 分钟,精度为 1 秒”的结果看起来已经像一个错误,因为所有条目的间隔为 00:05:01,而不是 00:05 的平均值: 00 符合预期。
    • @MarkStosberg 没错,准确度定义的时间窗口看起来是累积的。如果您认为这是一个错误,我很乐意将它提交到 systemd 需要的任何地方(可能是 github?)当然,以“1us”的准确性,可能需要更长的时间才能注意到滑倒......
    • 您说得对,如果“1 秒”的精度每个周期滑移 1 秒,我们可以推断“1us”的精度每个周期滑“1us”。您可以在此处搜索和提交错误:github.com/systemd/systemd/issues 还可以查看 Changelog/History 文件,看看是否有提到在比您的版本新的版本中修复了这个问题。
    • @MarkStosberg,让我们看看会发生什么...github.com/systemd/systemd/issues/4083 — 感谢您提供链接!
    【解决方案2】:

    基于the docs for systemd.timers,计时器没有滑动。计时器“每 5 分钟运行一次”,但每 5 分钟窗口内的执行时间是随机的。当您不希望在特定时间间隔发生“踩踏”活动,但希望平衡后台服务的负载时,这通常是集群中理想的行为。

    正如文档所说,

    要获得最佳精度,请将 [AccuracySecs] 设置为 1us。

    通过创建一个虚拟服务来检查自己,该服务只是每 5 分钟写入一个日志文件或日志,并让它运行半小时。尝试使用和不使用AccuracySecs=1us

    我预计两次运行都会每 5 分钟运行一次,AccuracySecs=1us 恰好每 5 分钟运行一次。

    【讨论】:

    • 我认为运行测试,正如你所指出的,将是一个好主意。所以我创建了一些文件,非常简单(以最少的方式让事情正常工作)并等待了一段时间......在我的结果中,我可以看到滑点。不幸的是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 2011-03-05
    • 1970-01-01
    • 2017-12-24
    • 2011-03-26
    相关资源
    最近更新 更多