我有以下问题:
领导服务器创建具有开始时间和结束时间的对象。创建对象时设置开始时间和结束时间。
对象的开始时间设置为领导节点上的当前时间,结束时间设置为开始时间+增量时间
线程会定期唤醒并检查任何对象的结束时间是否小于当前时间(因此对象已过期) - 如果是,则需要删除该对象
< / LI> 醇>只要事情在领导节点上顺利运行,所有这一切都可以正常工作。如果领导节点发生故障,则其中一个跟随节点将成为新的领导者。 (领导者和关注者节点之间将有复制(RAFT算法))
现在对新领导人来说,时间可能与之前的领导者截然不同。因此,步骤3中的计算可能会产生误导。
解决这个问题的一种方法是保持节点(领导者和追随者)的时钟同步(尽可能多)。
但我想知道是否有其他方法可以解决分布式节点的“过期”问题?
更多信息:
答案 0 :(得分:1)
我看到过两种不同的到期方式。这两种方法都保证时间不会回归,如果通过NTP同步时钟或者使用系统时钟会发生什么情况。特别是,两种方法都利用芯片时钟来严格增加时间。 (Javaland中的System.nanoTime
。)
这些方法只有 才能过期:时间不会消退,但时间可能会变得更慢。
第一种方法有效,因为您使用的是raft集群(或类似的协议)。它通过广播从领导者到复制品的不断增加的时钟来工作。
每个对等体维持我们称之为近乎实时运行的群集时钟。领导者定期通过木筏广播时钟值。
当对等体接收到该时钟值时,它会记录它以及当前的芯片时钟值。当对等体当选为领导者时,它可以通过将其当前芯片时钟与最后记录的芯片时钟值进行比较来确定自上一个时钟值以来的持续时间。
奖励1 :集群时钟值可以连接到每个转换,而不是新的转换类型,并且在安静时段,引导者进行无操作转换只是为了向前移动时钟。如果可以,请将它们连接到筏心跳机构。
Bonus 2 :我维护了一些系统,其中每个转换的时间都会增加,即使在相同的时间内也是如此。换句话说,每个转换都有一个唯一的时间戳。为了使其工作不会太快地推进时间,您的时钟机制必须具有可以覆盖预期转换速率的粒度。毫秒仅允许1,000 tps,微秒允许1,000,000 tps等
每个对等体仅在接收每个对象时记录其芯片时钟并将其与每个对象一起存储。这可以保证对等体永远不会在领导者之前使对象到期,因为领导者记录时间戳,然后通过网络发送对象。这创造了一种严格的先发生关系。
然而,第二种方法很容易受到服务器重启的影响。许多芯片和处理环境(例如JVM)将在启动时将芯片时钟重置为随机值。第一种方法没有这个问题,但更昂贵。
答案 1 :(得分:0)
如果你知道你的节点被同步到某个绝对时间,在某个epsilon中,简单的解决方案可能只是将epsilon烘焙到你的垃圾收集方案中。通常使用NTP,epsilon约为1ms。使用像PTP这样的协议,它将远低于1ms。
但绝对时间并不存在于分布式系统中。尝试依赖它可能是瓶颈,因为它意味着所有节点都需要通信。避免它和一般同步的一种方法是使用vector clock或间隔树时钟保持相对的事件序列。这避免了在绝对时间上作为状态同步的需要。由于序列描述了相关事件,因此暗示只有具有相关事件的节点才需要进行通信。
因此,使用垃圾收集,可以使用节点序列号将对象标记为陈旧。然后,不是垃圾收集器线程检查活跃度,而是可以收集对象作为序列号递增,或者只是标记为陈旧并异步收集。