请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

如何保证各个节点的时间一致性

看到代码中有一段随机上锁

// 上锁
// 随机睡眠(0~1s)
//time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)

之前还没有想明白,发现每次都会并发执行,以为是代码哪里出错了

最后才明白,是因为定时,到了时间执行完了,然后释放了锁和租约。
然后因为随机睡眠了,后面的节点执行的时候发现锁已经释放了,然后就又执行了一遍。

那么,问题来了,如果服务器很多,而且部署在各个机房,应用也被部署在各个机房,如果如何保证时间的一致性,保证不了时间的一致性,就可能并发执行。

之前看到谷歌的机房部署在世界各地,有些机房还在太空之中,因为太空中的卫星上的运行速度很快,根据狭义相对论,运行速度越快时间越慢,一年下来时间就会相差几毫秒,谷歌简单粗暴的方式就是用原子钟来校对时间,取一个统一的时间。

那么如果在项目中需要保证时间的一致性,需要如何去做?

正在回答

1回答

1,校准时间在linux下是依靠ntp守护服务实现的,误差通常很小,我们只需要给予一定的随机打乱即可,不需要下太多功夫。

2,因为任务通常不是瞬间退出的,所以多个worker因时间误差接二连三调度的情景是可以容忍的(PS:任务需要自己做幂等性,就像一个对账任务启动后应该先检查之前对账是不是已经做完了一样)。

3,我们用多牛逼的技术,都需要考虑成本,能把问题解决,同时保障系统简单可靠就很好了。更为复杂的架构就是中心调度,需要master直接在etcd中调配任务到具体worker,这种情况下异常case会增多,所以课程并没有做这种方案。

0 回复 有任何疑惑可以回复我~
  • 提问者 慕函数7881054 #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2019-03-08 09:22:25
  • 提问者 慕函数7881054 #2
    最近遇到一个问题,现在我不是直接在机器上执行任务,而是执行一些调取数据任务,但原理是想通的,需要在每一分钟获取es的数据,然后将数据比对清洗,然后入库到influxdb中,这就需要这些任务必须要开协程去完成,因为请求接口获取数据,数据的清洗,比对,然后入库到influxdb和mysql中的时间可能会超过一分钟,如果不并发开协程,etcd中就没有释放锁,然后就会导致数据获取缺失,所以必须要开协程并发执行。然后就发现如果开了协程去执行。写好程序放到六个docke执行,就发现,数据获取重复了,发现TXN锁根本就没有起作用。之后就想,要不加个定时器延时5秒,情况有所好转,但偶尔又会出现重复执行。但这个数据必须要保持一致性,不能重复入库数据,感觉TXN事务锁不是很靠谱。老师,有什么解决的办法吗?
    回复 有任何疑惑可以回复我~ 2019-03-08 09:40:15
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信