Windows Azure上的时钟同步质量如何?

30

我正在寻找关于Windows Azure上虚拟机之间的时钟偏移量的数量估计 - 假设所有虚拟机都托管在同一数据中心。我猜测一个VM和另一个VM之间的平均时钟偏移量低于10秒,但我甚至不确定这是Azure云的保证属性。

有人对这个问题进行过一些定量的测量吗?


3
+1 - 很好的问题。我"期望"答案应该比10秒要接近得多-在数据中心内,NTP应该能够提供不到0.01秒的时间同步,但我没有看到任何地方引用过类似的数字。 - Stuart
Windows Azure对于任何严肃的应用程序都是无用的,因为它存在这个问题(不仅仅是Azure...我尝试过的所有“真正的云托管”平台都有这个问题)。我真正不理解的是,这是如何发生的,以及“我们将为您提供托管平台,在该平台上,服务器之间的时间漂移超过10秒”何时成为有效选项。我的意思是,这就像我开发了一个网站,在该网站上你只能在奇数秒登录,并说-这不是错误,出于安全目的,它是有意这样工作的。 - nikib3ro
1
@GregD 40年前的分布式系统与今天的分布式系统在并发用户和可访问性方面有很大不同(感谢互联网)。以竞标应用程序为例 - 如果您有多个Web服务器(用于处理巨大负载),想象一下它们的时钟相差几秒钟 - 您将无法确定哪个出价何时到达。显然,此问题可以通过在单个服务器上保留系统中关键时间部分(例如数据库)来解决,但这并不能稳健地解决问题(任何重要的DateTime.Now代码都需要在该服务器上)。 - nikib3ro
@kape123 你在逗我吧?难道你认为像 eBay 这样的“竞价网站”没有处理过你所描述的问题吗? - Eoin Campbell
@EoinCampbell 我自己建了几个竞标网站,我用它作为一个显而易见的例子,说明你不能轻易地在Azure上托管它,因为时钟漂移的问题。eBay也是一样,它不使用Azure...所以你说的话是无关紧要的。请再次阅读我写的内容。 - nikib3ro
显示剩余3条评论
6个回答

31

我终于决定自己做一些实验。

有关实验协议的几个事实:

  • 与其寻找到一个参考时钟的偏移量,我只是检查了Azure VMsAzure Storage之间的时钟差异
  • 使用下面粘贴的HTTP hack获取了Azure Storage的时钟时间。
  • 在Azure的North Europe数据中心进行了250个小VM的测量。
  • 使用Stopwatch测量存储和VM之间的延迟始终低于1ms,用于最简单的未经身份验证的请求(基本上返回带有Date: HTTP标头的400错误)。

结果:

  • 大约50%的VM相对于存储具有大于1秒的时钟偏移量。
  • 大约5%的VM相对于存储具有大于2秒的时钟偏移量。
  • 时钟偏移量接近3秒的观测值少于1%。
  • 少数离群值接近4秒。
  • 单个VM与存储之间的时钟偏移通常从一次请求到下一次有+1/-1秒的变化。

因此,从技术上讲,我们离2秒的公差目标并不太远,尽管对于数据中心内同步而言,你不必将实验推得太远以观察接近4秒的偏移量。如果我们假设时钟偏差服从正态(即高斯)分布,那么我会说依赖低于6秒的任何时钟阈值都可能导致调度问题。

/// <summary>
/// Substitute for proper NTP (Network Time Protocol) 
/// when UDP is not available, as on Windows Azure.
/// </summary>
public class HttpTimeChecker
{
    public static DateTime GetUtcNetworkTime(string server)
    {
        // HACK: we can't use WebClient here, because we get a faulty HTTP response
        // We don't care about HTTP error, the only thing that matter is the presence
        // of the 'Date:' HTTP header
        var tc = new TcpClient();
        tc.Connect(server, 80);

        string response;
        using (var ns = tc.GetStream())
        {
            var sw = new StreamWriter(ns);
            var sr = new StreamReader(ns);

            string req = "";
            req += "GET / HTTP/1.0\n";
            req += "Host: " + server + "\n";
            req += "\n";

            sw.Write(req);
            sw.Flush();

            response = sr.ReadToEnd();
        }

        foreach(var line in response.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
        {
            if(line.StartsWith("Date: "))
            {
                return DateTime.Parse(line.Substring(6)).ToUniversalTime();
            }
        }

        throw new ArgumentException("No date to be retrieved among HTTP headers.", "server");
    }
}

干得好!我们能从中得出任何关于最大预期时钟“修正”的结论吗?例如,2秒的偏移是否意味着时钟在某个时候也会被纠正2秒? - Timo

8
我最近与Azure产品团队的某人进行了有关时钟同步的交谈,更多的是出于兴趣而非其他。我收到的最新回复是: “虚拟机和服务在启动时直接从底层Hyper-V平台获取时间,并从那时起由服务维护时钟。要在分布式系统中实现真正的时间同步,您将需要在应用程序层面和/或使用引用单个时间服务器的服务进行操作。”

3

根据我的经验,我不会依赖Azure虚拟机的系统时钟来处理任何关键性任务。我偶尔会看到几分钟的时间差异,这与您所期望的情况不符。


有趣的 :-) 这正是我想更好地了解的情况。 - Joannes Vermorel
1
不幸的是,这也是我正在经历的。我有一个开放的API,我依赖于DateTime.UtcNow,并且在我使用的3个实例(额外小)中,差异变化高达10秒。考虑到所有我的开发服务器都同步,为什么微软不能使他们的实例同步?这是不可接受的。 - gimlichael
对我上一条评论的跟进;看起来,在大约1小时的热身期之后,实例开始同步。截至目前,有+1/-1,正如Joannes所指出的那样。仍然很奇怪,需要这么长时间。 - gimlichael

3
这是分布式系统和虚拟机的经典问题 - 时钟偏差。一种可能的解决方案是使用Azure调度程序在每个虚拟机上ping一个端点,以重置你的时钟 - 或者至少告诉你差异会是多少。这样,你的偏差不会增加,甚至可以计算通信延迟的偏移量。这样,你将得到毫秒级别而非秒级别的精度。
当然,你也可以采用另一种方式,让虚拟机上的服务周期性地通过ping时间服务器来管理时钟。我不确定超级监视器是否会允许你干扰它的时钟,但你只需要一个应用程序可消费的偏移量即可。
总之...永远不要相信虚拟机上的时钟,尤其是在分布式系统上。请注意,这个时钟问题是许多大学正在积极研究的一部分。比如:https://scholar.google.com/scholar?hl=en&q=distributed+system+clock&btnG=&as_sdt=1%2C48&as_sdtp=

1

1

如果你正在构建分布式系统,除非使用特殊的硬件措施(例如Google Spanner中使用的),否则不能信任时钟同步。即使在那里,也会使用特殊算法来解决可能的时钟偏差冲突。 然而,有许多算法可以解决分布式系统中的这个问题:逻辑时钟、向量时钟、Lamport时间戳等等。请参阅Andrew Tanenbaum的经典著作《分布式系统:原理与范例》。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接