系统和架构做的越多,就越觉得架构是个取舍的艺术。没有所谓的银弹可以把很多问题一次性解决掉,也就不纠结让业务给你一个偏于理想的迭代节奏与业务保证业务怎样怎样。
前一段时间一个朋友说了去快手面试的经历,背景应该是让做一个秒杀场景的系统设计。
朋友当然说了类似于“没有明确场景的架构设计都是耍流氓”,朋友的回答围绕于流量漏斗、最终一致去回答,但面试官核心要求是100w tps打到了数据库上你怎么解?
这个事情就很难搞,首先100w tps怎么来的?既然这么多流量都是真实流量,有状态服务和存储服务不具备足够的容量可以支撑吗?肯定要加机器。具体怎么解决流量过滤和数据一致肯定需要看具体场景,比如不同领域下的服务对于数据一致性容忍程度是不一样的,背后肯定方案也不一样。脱离业务场景谈架构果然是耍流氓,最后这个面试是不欢而散。
做秒杀架构主要解决两件事情,一个是高流量,一个是数据一致性。这两个方向问题回答好了,理论上就没有问题了。我自己做面试官心里当然想候选人给我一个完备的方案,但是我也知道在有限的时间、有限的场景下,光靠嘴聊是很难聊得完备的,所以我一般观察两点。
一个是普世方的法论,就是有些事情是是永远做不到完美的,也不要期望做到完美,但是你需要告诉我为什么做不到完美,他的本质是什么,怎么做到趋于完美。
第二个是看方案的完备性,什么意思呢?是希望候选人可以给出这个核心问题之外的一些考虑,我个人理解是一种扩展性的体现,如果一个系统负责人不能考虑核心问题之外的一些事情,系统的可靠性与扩展性就很难提前规划出来,这样的系统就变成了故障驱动型系统了,就是出了问题做次迭代,永远跟在故障之后擦屁股。
那在分布式系统下有哪些理论,可以帮助我们在架构中的方案更合理呢?
FLP理论
FLP理论说的是不可能原理,原论文指出:在网络可靠,但允许节点失效的最小化异步模型系统中,不存在一个可以解决一致性问题的确定性共识算法。
简单来说,就是不要在分布式系统中的异步场景下浪费时间去设计出所有场景都能实现共识的方案。
为什么呢?
在分布式架构下,节点之间通信是异步的,如果一个节点进程停止工作了,其他节点是不能确认是消息延迟导致的,还是真的挂了,还是会尝试进行消息读取。
FLP理论告诉我们,一致性算法的可靠性是无法保证的,不存在一个可以在异步网络上容忍各种故障且保持一致性的分布式系统。
无论paxos还是raft,如果你想要安全,那么理论上都会产生无法表决通过的死循环,每次的状态变化都可能是当前状态的一种分支情况,所以在分布式系统中永远不能能达成单体应用级别的一致性。
在现实场景中,我们采用TCP协议,保障消息健壮性、不重复、不乱序,每个节点通过NTP时钟同步
CAP理论
CAP包括:一致性、可用性、分区容错性。
一致性:当系统的更新操作成功并返回客户端后,后续所有节点对于数据的访问应该都可以获取新值;
可用性:分布式系统可以正常对外提供服务;
分区容错性:分布式系统遇到某些节点故障或网络分区故障时,仍可以对外提供服务;
CAP理论告诉我们,在分布式系统下不能同时满足一致性、可用性、分区容错性三个特性,只能取其二。而在分布式环境下,网络问题是需要满足的,也就是P是需要的。所以大部分情况下关注于AP或CP即可。
BASE理论
BASE理论是对CAP理论的延伸,是对于CAP中强一致性的进一步延伸,提供软状态、最终一致性。
BA(基本可用):在分布式系统出现故障时,允许损失部分可用性,保障核心可用,比如电商双十一时,为满足商品购买链路的稳定性,可以降级掉用户修改地址这些功能。
S(软状态):允许系统之间出现中间状态,什么意思呢?不是简单的刚性成功 or 失败,而是在分布式系统下多副本中出现中间状态,这种中间状态是由于多个副本复制延迟导致的,比如mysql replication异步复制。
E(最终一致性):指的是系统中所有副本数据经过一定时间之后,可以达到最终一致的状态。
ACID原则
ACID是:原子性、一致性、隔离性、持久性。
概念包括:
原子性:每次操作是原子的,要么成功,要么失败;
一致性:是强一致性,没有中间状态;
隔离性:各个操作彼此隔离,互不影响;
持久性:数据状态一旦提交,是持久的,不会失效;
ACID一般用于关系数据库的事务定义,追求的是强一致性;
BASE是在分布式系统下,牺牲掉对于一致性的约束,以最终一致性的方式提供一致性,换取性能和可用性;
两种方案是完全相反的设计哲学,具体怎么用就需要看场景了。
所以架构是取舍的艺术,脱离场景谈架构都是耍流氓,先基于场景,画一个框,在框内找到一个确定性的问题,找到这个问题的本质,给出合适的解。
其他分布式原理,详见: