前言
最近看了一些蚂蚁金服的面试分享文章,里面多次提到分布式系统涉及的概念,比如分布式事务、接口的幂等性,乐观锁、数据一致性等。笔者一时也说不清楚,后来查询了一些资料,整理下来,以备后用。
系统衡量关键指标
QPS:单位时间内处理完请求次数。一个系统的qps是100,则代表一秒钟内处理100个请求。
TPS:单位时间内处理完事务的次数。在分布式系统中,对应的是分布式事务。
并发量:在某一时刻,请求同时到达的数量。最大并发量,即系统能同时处理的最大请求数量。
响应时间:系统处理一次请求的平均时间。
QPS(TPS)=并发量/响应时间 或 QPS(TPS)=请求总数/总时长
举例:
一个典型的上班签到系统,早上8点上班。7点半到8点这30分钟的时间里用 户会登录签到系统进行签到。公司员工为1000人,平均每一个员上登录签到系统的时长为5分钟。能够用以下的方法计算。
QPS = 1000/(30*60) 事务/秒
平均响应时间为 = 5*60 秒
并发数= QPS*平均响应时间 = 1000/(30*60) *(5*60)=166.7
CAP原则
C(consistency):一致性。在分布式系统中某一个节点写入后,读其他节点都能读到最新写入的数据。
A(availability):可用性。系统保持可用,但是不保证数据是最新的。
P(partition tolerance):分区容错。一个分布式系统存在多个网络节点,当网络节点之间由于网络断了,节点之间不能通信,造成分区网络时,系统仍旧可以继续工作。
CAP原则就是以上三种只能满足其中的两种。不可能同时满足三种。
一般网络都不可能保证100%没问题,所以每个组合都包含P,即CA组合几乎是不存在的。重点关注的是CP、AP组合。
本地数据库事务ACID
A:原子性(Atomicity),一个事务内的所有操作要不全部成功,要不全部失败,没有中间状态。
C:一致性(Consistency),事务之前之前和执行之后,数据库状态保持一致。
I:隔离性(Isolation),指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。查询数据时,要不就是事务处理之前的状态,要不就是事务处理之后的状态,中间状态看不到。
D:持久性(Durability),指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。
分布式事务
分布式系统就是把一个大的集成系统拆分成多个子系统,这些子系统分布在不同的机房,处理一个请求就要经历多个子系统。比如电商,用户下订单后,由订单系统和库存系统来处理。一个分布式事务就包括,订单系统扣除用户余额以及库存系统减少一件商品的库存。这两个操作是要同时完成的,要么都成功,要么都失败。分布式事务的方案有2PC、TCC、MQ等。
BASE原则
BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。现在很多主从数据库都满足最终一致性,而不是强一致性。
幂等性
用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品使用支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时不会再扣款,并返回成功结果。采用全局唯一ID来保证幂等性。
悲观锁
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步原语synchronized关键字的实现也是悲观锁。
乐观锁
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。
以上介绍了分布式中的一些常见概念,理解了这些概念就容易更好的设计出分布式系统。如何保证分布式系统中的数据一致性呢?自己进行思考。