有的人30岁去世了,有的人40岁也走了。
所以你一定要明白,我们不是等老了才会死,而是随时随地都有可能死。
人生其实大部分是没有意义的,百年以后时间会抹平你存在过的所有痕迹,若硬说人生的意义,那就是你活着这几十年的体验。
所以别让不开心的事挡住了你短暂的人生,想什么活就怎么活,用心去品尝每一口饭菜,尽情去欣赏每一处风景,勇敢的热爱生活。
今天钉钉直接通知我们从明天开始,中午休息缩短半小时,就是作息时间从 8 点半到 17 点半改为 8 点半到 17 点。这是正常的。不正常的像我们 C 班改为 7 点半到 4 点。8 小时工作制不变,其实倒也不影响,冬天下班早,路上还安全,只是早上爬不起来。原本中午还能睡个午觉,现在不行了,顶多吃个饭的时间。习惯午觉的姐姐下午上班可能会难受。

公司研究,指的是老板自己想的。工厂日常工作时间,意思是这针对我们工厂。像门店和公司那边不受影响。也就这点能耐了,每天就 8 小时,看你怎么折腾?
本来仓库三个人,其中一位升主管兼顾发货,基本上偏向发货了,仓库就剩俩。现在作息时间错开,顶多仓管算1.5 个人吧。最近几天有人受不了,提出了离职。我相信年底会更多。像我这样的挣生活费的人不多,大家谁为了这点工资还受气呢。以为大环境不好,就会一直妥协。也算是随了老板想裁员的心了。
现在给仓库派活也理所当然了,周一有个机器从江苏无锡用货拉拉运到我们工厂,到达时间是晚上 7 点多,也不是很着急,不能第二天一早安排发货吗。就叫仓库安排人晚上接收。今天还是一样的情况,说要晚上 9 点到,也不协商一下发货时间和派送时间,就叫仓库安排人接收。后来我们领导问货拉拉司机可以第二天早上派送,这才不用加班。
周一晚上接收的机器是 2kg 的烘焙机,用来烘豆子的。周二晚,我们四个男的,工厂唯一四个男的,一起把它拉到二楼组装好了。这点我很不理解——我们一楼是车间,烘焙和分装都在一楼,生豆也在一楼,他们非把这个烘焙机搬到二楼办公室里。
今天中午老板一来就要豆子烘,没错,我们早上 7 点半打的豆子,他中午来烘,请问我们提前一个小时来上班打豆子的意义在哪里?豆子都备好了,我们领导刚好吃完饭,就得到楼下拿豆子上来给他烘。我吃完饭不想被打扰就直接去车里睡了。幸亏我去了车里,中午老板在那烘豆子,噪音和烟雾整的整个办公室乌烟瘴气,谁能安安静静的午睡。还说有爱有光呢,一点不体谅员工的辛苦,最后一个小时的午睡时间都被他搅和了。这种不尊重人的老板不值得我们去尊重。
很奇怪,这么大的烟,怎么消防没反应呢?有问题!
今天聊一下时间的话题。在分布式系统中,“时间” 是一个挺有趣,但是很难处理的东西。我把自己的理解简单整理下来。
首先,单一节点的物理时钟是不可靠的。
物理时钟本身就有偏差,可是除此之外,可以引起节点物理时钟不准确的原因太多了,比如 clock jump。考虑到 NTP 协议,它基于 UDP 通信,可以从权威的时钟源获取信息,进行自动的时间同步,这就可能会发生 clock jump,它就是说,时钟始终会不断进行同步,而同步回来的时间,是有可能不等于当前时间的,那么系统就会设置当前时间到这个新同步回来的时间。即便没有这个原因,考虑到数据从网络传输的延迟,处理数据的延迟等等,物理时钟是非常不可靠的。
如果一个分布式系统,多个节点想要仅仅依赖于物理时钟来完成什么操作,那么只能祈祷运气足够好了。在 《从物理时钟到逻辑时钟》这篇文中,我已经介绍了对于物理时钟不可靠的问题,我们有一个解决的办法,就是引入 Lamport 逻辑时钟,或者使用向量时钟,这里就不赘述了。
分布式系统中什么样的执行结果最难处理,成功还是失败?其实都不是,最难处理的结果是超时,因为执行超时了,但是系统却并不知道它:
所谓超时,一个显然的问题是,超过多少时间才算超时?往往没有一个公式,更没有一个标准答案,我觉得《Designing Data-Intensive Applications》这本书里面对这一点总结得很好——对于超时时间的定义,其实就是一个 tradeoff,一个基于 failure detection delay 和 risk of premature timeouts 之间抉择的平衡。如果超时时间设置长了,就会减少超时判定的误杀,但是对于系统失败的识别就会延迟;反之,如果超时时间设置过短,那就会触发更多看起来是超时的 case,但是它们本身其实并没有真正超时。
通常来说,对于超时的处理,其实办法也不多。一种是放弃,一种是重试。就像消息投递,如果要保证 “至多投递一次”,那在投递超时后,就直接放弃;如果要保证 “至少投递一次”,那在投递超时后,就重试。如果要重试,那就需要引入保证幂等性的机制。
分布式事务 SAGA 对于超时的处理,其实也是遵照上面的原则,在系统内单步都成为事务的基础上,把流程视作一个状态机,无论单步操作是成功还是失败,都会根据清晰的预定义逻辑,触发相应的正向流程或者反向流程,可是唯独超时,多数情况下最有意义的事情就是重试,也只能重试,因为谁也不知道它究竟实际是成功了还是失败了。
说完操作超时,再来说一下节点超时。很多分布式系统中都会使用一种 lease(租约)的机制,比如一个集群中的 leader,作为 leader 会扮演不同的角色,但是必须要 renew 这个 lease,否则超过一定的时间,无论它给不给响应,它都会被开除出 leader 的角色,而 follower 会重新选举(或者其他方式)一个 leader。
比较难处理的是,如果这个节点本来是被 hang 住了,导致了超时,它也已经被踢下 leader 的角色,但是之后它 “活” 过来了(比如经过了一个超长时间的 GC),它还以为自己是 leader,继续去干 leader 干的事,变成了一个假 leader。这其实就是出现了脑裂,本质上是一个一致性的问题。这种情况比较难处理,因为即便有 heartbeat 不断检测,在每两个 heartbeat 的间隙,可能这种重要的变动就发生了。
要解决这种问题,需要使用 token fence 的方法,即让每次最关键的状态数据的更改,携带一个单调递增的 token,这种情况下这个假 leader 发起更改的 token,已经小于系统中最新的 token 了,接收这个数据更改的子系统应该拒掉这个请求。上面说的节点超时的情况我在《谈谈分布式锁》里面有详细说明。
有两种时钟是计算机普遍支持的,一种叫做 time-of-day clock,就是我们一般意义上的时钟,代表着相对于 1970 年 1 月 1 日的 epoch 时间,也就是 Java 里面 System.currentTimeMillis() 返回的。网络时间协议 NTP 就是用来同步计算机这个时间的。
不过,其实还有一种时钟,叫做 monotonic clock(单调时钟),在 Java 里面相应的接口是 System.nanoTime()。这个时钟有一个特点,就是它永不回头。对于 time-of-day clock 来说,时间是可能 “回头” 的,对于很多应用来说,时间回头是要命的。不过这个时钟给出的具体时间却是毫无意义,如果在不同的机器上调用 System.nanoTime(),会得到完全随机的结果。API 的名字是纳秒,可是这个时钟并不给出到纳秒的时间精度,它的作用是用来帮助计算间隔时间的:在同一个节点,第二次调用的时间减掉第一次调用的时间,这个结果(时间间隔)是严格递增(不回头)的。从这个意义上说,除去时间这个视角本身,这个时钟更像是一个单调的计数器。既然是单调的计数器,就可以用来帮助产生系统严格自增的 ID。
下面是 System.nanoTime() Javadoc 上面的解释:
Returns the current value of the most precise available system timer, in nanoseconds.
This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.
一般来说,我们都知道计算机的时钟有误差,可是这个误差是多少,差 1 毫秒还是 1 分钟,并没有任何严格保证。绝大多数接触到的时间 API 也是如此,可是,Google 数据库 Spanner 的 TrueTime API 却。它使用了 GPS 时钟和原子钟两种完全独立的机制来冗余某一个机制失败导致的时钟问题,增加 reliability。此外,它还有和 System.nanoTime() 一样的严格递增的特点。
它有三个核心 API,很有意思:
有了 TrueTime,这让分布式系统中,本来无法通过物理时钟解决的问题也变得可解决了。比如对于操作冲突的问题,现在的新办法就是等一个 buffer 时间,TrueTime 认为已经前一个操作的结束时间肯定已经过去了,再来启动后一个操作。当然,这个方法的缺点是 throughput,因为整个操作周期因为 buffer 时间的关系变长了。
《四火的唠叨》文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接
今天深圳稍微比昨天暖和了一些,我也晒了会儿太阳。
今天下午,在博客群看大家讨论,虽然我插不上几句话,但是能够明显的感受到大家认真讨论的氛围。我起身去厕所方便了一下,而就是这短短几十秒钟,让我想起了一些事情。
在十年前,我加入了一个音乐爱好者的群,叫「橘子党」。我们都是在虾米音乐上相识。平时大家在群里聊聊爱好,唠唠家常,是我那些年最活跃的群。我们每年都会征集大家的投稿来发布虾米歌单。我们还有自发组织的面基。我们还为群聊周年庆设计生产的帆布袋、T 恤、徽章。群里有个相册,会上传一些群员的个人照和面基照。在虾米音乐还没没落之前,我一直觉得,我们会像这样一直聊下去,直到每个人都互相见过面。
今天「橘子党」的群又突然聊了起来,然后不出奇的又聊到了一些以前的事情。我翻看了一下群相册,看到了那些渣渣画质的手机和一张张青涩的面孔,感觉他们即熟悉又陌生,他们曾经在我生活中占据了很多一部分,而虾米音乐消失之后的这几年,他们也好像从我的生活中消失了一样。现在,他们有的成家了,本来以前还在上学的现在也结婚了,我如今也要三十一了。
再回过神来,坐在电脑前,看着中文博客群聊里仍在继续讨论着,心中不由感慨,我们这个以博客之名相遇的群,从建群到现在,也经历过一些让人印象深刻的事情。我退过群,来后也又加了回来。群聊也被封了然后重组过。这些年来每天都能看到大家聊各种话题,从博客,笔记,天文地理,社会政治,音乐游戏等等等等,可以说是我自「橘子党」之后坚持活跃最多的群,也是我在众多群聊中比较青睐的群。
可是这个世界上什么东西都会过期,苹果会过期,音乐听多了也会腻。在时间的洪荒面前,不知道十年后,大家还会像现在这样活跃如初吗?现在耳熟能详的他们,十年后还会像今天这样在群里谈天论地吗?十年后,还会继续写博客吗?