time - 如何考虑分布式系统中的时钟偏移?

标签 time synchronization distributed-system clock

背景

我有一个由多个分布式服务组成的系统,每个服务都不断生成事件并将其报告给中央服务。

我需要呈现一个统一的事件时间线,其中时间线中的顺序对应于事件发生的时刻。事件发生的频率和网络延迟使得我无法简单地使用到达中央收集器的时间来对事件进行排序。

例如在以下场景中:

sequence diagram

E1 需要在 E2 之上的时间线中呈现,尽管之后到达收集器,这意味着事件需要带有时间戳元数据。这就是问题出现的地方。

问题

由于环境设置方式的限制,无法确保每台计算机上的本地时间服务都能可靠地了解当前 UTC 时间。我可以假设每台机器都可以准确地测量相对时间,即时钟速度足够接近,可以使短时间跨度的测量相同,但是 NTP 错误配置/分区等问题使得不可能保证每台机器都同意当前 UTC 时间。

这意味着简单地为每个事件发生时生成本地时间戳,然后使用它对事件进行排序的简单方法是行不通的:每台机器对于什么是通用时间都有自己的看法。

所以问题是:如何恢复时钟不一致的分布式系统中生成的事件的顺序?

我考虑过的方法

我在网上找到的大多数解决方案都尝试synchronize all the clocks ,这对我来说是不可能的,因为:

  • 我不控制有问题的机器
  • 时钟不同步的首要原因是网络不稳定,而我无法修复该问题

我自己的想法是每次生成事件时查询某种中央时间服务,然后用检索到的时间减去网络飞行时间来标记该事件。这变得很棘手,因为我必须向系统添加另一项服务并确保其可用性(如果其他服务无法访问此服务,我将回到零)。我希望有一些聪明的方法可以做到这一点,而不需要我以这种方式集中计时。

最佳答案

一个简单的解决方案(最后受到您自己的启发)是定期 ping 我称之为时间源服务器的设备。在 ping 中包含服务的芯片时钟;时间源与此相呼应并包含其时间戳。然后,服务可以推断出往返时间,并猜测时间源的时钟大致在往返时间/2 纳秒之前的时间戳。然后,您可以使用它作为本地芯片时钟的偏移量来确定全局时间。

您不必为此使用不同的服务;收集器服务器就可以了。重要的是,您不必在每次请求时都要求调用时间源服务器;它将其从关键路径中删除。

如果暂时不需要锯齿波函数,可以smooth the time difference

恭喜,您已经重建了 NTP!

关于time - 如何考虑分布式系统中的时钟偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46458089/

相关文章:

c# - 数据库队列的并行处理

linux - 1 个线程与 5 个线程用于分布式系统通信?

java - 将标准时间转换为传统时间

c# - 如何随时间更改数据库列值?

c# - 等待任何线程完成,而不是全部

java - 隐蔽同步

c - ZMQ多部分冲洗器:是否可以通过ZeroMQ接收通过多部分消息接收的多部分总数,而无需全部读取?

javascript - switch div 函数中 JavaScript 的时间延迟

ruby-on-rails - Ruby 方法的测量和基准测试时间

c# - 同步两个 DataGridView 的水平滚动事件