恼人的网络时延
在分布式环境中,服务和服务之间通过网络进行通讯,在网络上,不可避免的存在网络时延。正因为网络时延的存在,才导致了一些不可控因素的发生,才让整个分布式系统的行为变得极为复杂。
两个节点之间的网络时延,应该遵循泊松分布。没有严格的证明,但是时延 0 和时延迟超大为长尾事件,这两点和泊松分布比较类似。
这个分布不是我们今天要讨论的重点,我们今天要说的是这个时延会带来的影响。
没有准确的全局时钟
由于时延的存在,分布式系统内部不可能存在严格同步的时钟体系。因为由一个点发布的同步信号,到达目标点需要时间,同时时间是不定的,没有办法准确计度算出时钟同步需要的时延。即使通过 gossip,也只能最大程度减少误差,而不能百分百消除误差。
所以,在分布式系统内,只存在逻辑时钟:如果事件 ei 导致了事件 ej,那么一定 ei 发生在 ej 之前。
逻辑时钟并不度量时间本身,仅区分事件发生的前后顺序。
消息乱序
由于网络时延的存在,A 系统发出的多个消息,到达 B 系统的顺序不一定按照发送的顺序。也就是又可以 msg2 比 msg1 先到。
所以在我们做消息系统的设计的时候,需要充分考虑乱序引起的影响。乱序可能会打破我们的状态机迁移规则。所以对于这种不正常的状态迁移,我们需要能合适的处理:
设计状态机的时候考虑乱序的场景。这个会引起状态机的膨胀,一般不采用。除非只有 1~2 个状态。
对于先到的消息,由于状态迁移不合法,可以 holding,重试,直到前置消息被处理。
对于同一个交易的消息,受理后不处理,进行排序,处理顺序正确的消息,乱序消息 waiting 前置消息。
同步的调用,也存在这种情况。现在的系统都是多线程(进程)的,所以先发起的调用可能后续后发起的调用被服务端处理。
副本不一致
考虑到网络时延迟,同时需要保证响应效率的话,我们一般采用异步复制的方式。这种方式下,副本一般会存在时延,在任何一个时间点,原始数据和副本之间存在一定量的不一致。
所以,这种异步复制的方式只适用于可以容忍副本不一致情况发生的场景。如:
immutable 缓存的备份:缓存只会被插入,不会修改。不一致就缓存击穿,而不会导致系统错误。
登陆 token 的同步:同时保证副本不会被主动写入。如果不一致就重新登陆,用户体验稍微有损,但不至于客诉。
用户认证信息:考虑到频率非常低,同时可以采用补偿的方式恢复。
总之,只要是不同步不影响大的系统正确性的场景。
容灾模式的考虑
这个在十八般武艺-高可用(https://xie.infoq.cn/article/05617ed25d83a89929bdb19e8)中已经提及。对于时延低的场景(同城副本),可以采用强同步。对于时延高的场景(跨洲副本),强同步影响性能,所以需要在 RPO 和 RTO 之间做平衡,同时需要考虑特殊的容灾方案。
总之,网络时延会对软件架构带来各种复杂的场景,我们在架构设计中要充分考虑。
版权声明: 本文为 InfoQ 作者【agnostic】的原创文章。
原文链接:【http://xie.infoq.cn/article/dc81d076c5b96913b27787f0c】。文章转载请联系作者。
评论