节点hrTime作为增量ID

时间:2019-07-14 18:31:18

标签: javascript node.js performance time

节点的process.hrtime如下:

假设有一个仅附加事件流应该保留(在数据库或文件中)。

  • 出于订购目的,使用node的{​​{1}}作为增量ID有多坏?
  • 可以安全地假设,由于hrtime就像单线程事件循环一样,因此在单进程的范围内不会有冲突或时间戳混乱吗?
  • 假设所有时钟都是NTP同步的,那么如何在为该事件流生成事件的多个主机之间使用它呢?
  • 假设所有时钟NTP都同步,那么多台主机之间的冲突概率是多少?
  • 由于这在很大程度上取决于系统的吞吐量,到什么时候会出现问题? 100、1,000、10,000、100,000个事件/秒?

是否有任何使用node进行此类引用的开源项目?

例如,系统可能不是在很高的吞吐量下运行,但考虑到高性能的CPU,一个动作可能会导致多个事件,因此很有可能在处理该动作的范围内多次调用hrtime ,将导致生成相同的毫秒级时间戳。

1 个答案:

答案 0 :(得分:0)

基本上,在Linux上,node的{​​{1}}深入到:

libuv使用libuv提供clock_gettime(CLOCK_MONOTONIC, ...)。寻找hrtime可以找到许多关于SO的答案。

按照手册:

  

CLOCK_MONOTONIC   由于POSIX所述,“过去的一些未指定时间”,因此无法设置并表示单调时间的时钟。在Linux上,该点对应于系统自启动以来已运行的秒数。   CLOCK_MONOTONIC时钟不受系统时间的不连续跳跃影响(例如,如果系统管理员手动更改时钟),但会受到adjtime(3)和NTP执行的增量调整的影响。此时钟不计算系统挂起的时间。

结果CLOCK_MONOTONIC不受NTP跳转的影响。但是由于相同的原因,它也不能用作绝对时间。 hrtime仅对计算两次执行之间的时间有意义。

但是,假设hrtime是单线程的,并且node的定义总是递增的(例如here),随后对CLOCK_MONOTONIC的调用应在增量方式,而不考虑吞吐量。

出于同样的原因,hrtime是单线程的,以下简单函数可以解决相同的毫秒分辨率时间(如图所示):

node

在高吞吐量下,上述解决方案效果不佳。一秒只有1000毫秒,因此理论上每秒具有1000个或更多事件的吞吐量,很可能会将let myLastTime = 0; function getMyTime() { const newTime = new Date().getTime(); if (newTime > myLastTime) { myLastTime = newTime; return myLastTime; } if (newTime === myLastTime) { myLastTime = newTime + 1; returm myLastTime; } // bad case if NTP jump for instance // and we need always increment time if (newTime < myLastTime) { myLastTime = myLastTime + 1; return myLastTime; } } 时钟移到未来,从而导致更多的问题无法解决。但是对于使用单个编写器的1000个以下事件(即非分布式多主机方案)而言,吞吐量可能会有所帮助。

在分布式多主机环境中,无论如何,时间都不是命令的参考。由于每个主机的时钟的行为可能有所不同,因此也会产生NTP跳跃影响等。

结论,为了保证顺序的持久性,应用程序应该依赖保证其顺序的基础存储,或者应用程序应该通过逻辑序号或类似的数字来管理订单。