理解一致性

原文:陈同学 | 理解一致性

最近工作涉及一致性问题,因此对概念加以梳理。将通过一些业务场景抽象出一致性的概念,再聊聊为什么一致性如此重要,最后看看后端常见技术如何保证一致性。

本文不会深究某个技术细节,主要是为了阐述对于一致性概念的理解,文中涉及到的技术概念可自行查阅资料。

不同场景下的一致性

转账场景

这是一个非常经典的场景。假设A有10元,B有0元,A给B转账10元,转账成功后,A有0元,B有10元,我们会说这个结果符合一致性。

假如转账成功后,A扣减了10元,余额为0;B却没有收到钱,余额也为0,我们会说这不符合一致性。

那我们判断符合一致性的依据是什么?表面上看依据是:转账之后A、B账户总额为10元

假如转账10元后,A、B账户余额分别为3元、7元,AB账户金额总和为10元,但我们根据常识就能判断,这不对!

因此,判断一致性的依据可以是:转账操作,转出方扣减的钱与接收方新增的钱应当相等

销售指标场景

这个场景完全脱离技术,可以思考

假设某公司销售团队本财年的业绩指标为销售额达到1亿,年底时,若销售额为8千万,Boss可能说还不错;若销售额为1亿,Boss可能开心的在年会表扬,咱圆满的完成了销售任务,团队提成丰厚;若销售额为2亿,Boss可能单独和大家吃饭,再发上高额提成。

那这里有一致性问题吗?一致性的规则又是什么?

我们假定一致性判断规则:如果销售额达到指标的70%,就符合一致性。因为销售指标总是夸大的,或者说是个努力的目标,假设达到70%就很不错。

那么,年底销售额8千万、1亿、2亿都符合一致性规则,假如销售额是1千万,公司可能因此垮掉,那么就不符合预期,造成了严重后果。

秒杀场景

假设商品库存100,1万人参与秒杀。

假如卖出商品数量超过100,我们认为这不符合一致性。那这里的一致性规则是:商品不能超卖,最多卖出100件

什么是一致性?

参考 Data Consistency Primer

通过上面三个场景,可以发现不同场景下 一致性 的规则并不相同。换句话说,一致性指的就是最终的结果是否和设定的规则保持一致!

因信息技术的发展,现在数据都直接存储计算机中(如数据库、磁盘等),因此技术人员聊的一致性往往指数据一致性

但计算机世界里难免出现问题,如:业务程序BUG、软件崩溃、机房损毁、光缆挖断等,但现实世界(商务世界)中首先是不允许出现数据问题,其次是不关心技术故障。因此,数据的一致性(即能得到符合规则的结果)就成了重中之重

保证数据一致性的技术手段

这里列举一些常见的保证数据一致性的技术手段或理论。

关系型数据库事务的一致性

我们最为熟知的就是事务的ACID特性,即原子性、一致性、隔离性、持久性。

原子性、隔离性、持久性最终的目的就是为了保证一致性。

Mysql与一致性

Mysql保证数据一致性的手段很多,例如:

  • 应用与Myql交互时,通过锁机制保障一致性

例如:更新数据时通过排他锁 锁定行记录,保证在数据修改期间没有其他事务更新该纪录。

  • Mysql事务的隔离级别

通过不同隔离级别解决并发操作时数据的脏读、幻读、不可重复读问题。

  • InnoDB引擎的日志机制

通过undo日志、redo日志来保证事务的原子性和持久性,确保事务要么全部执行,要么全部回滚,同时在故障情况下也能保证数据成功持久化。

乐观锁与悲观锁

乐观锁与悲观锁是一种思想,具体的实现有很多。因我们经常接触到这两种锁机制,因此这里单独拿出来举例。

  • 乐观锁例子

表设计时经常会加入 版本(version) 字段用于应用层的乐观锁实现,在更新数据之前,我们会比对数据库中记录的版本与当前记录的版本,如果版本一致,说明数据未被修改;否则应用层应当抛出异常。

这种方式避免了我们读到过期的脏数据,从而保证数据一致性。

  • 悲观锁例子1

Mysql的排他锁,在修改数据之前直接锁定行记录,在自己操作数据期间不允许其他事务修改数据。

  • 悲观锁例子2

Java中的锁机制,例如:synchronized关键字、对象锁、类锁都可以看作悲观锁,通过锁机制保护共享资源(或称为临界区)。

分布式与一致性

分布式场景下,事务的一致性变得更加复杂。

  • Mysql这种数据库提供了分布式事务。
  • 随着微服务思想的流行,现在越来越多平台基于微服务理念进行实施。此时,更多的是通过最终一致性方案来保障数据的一致性。

并发环境下的一致性

以Java多线程为例,由于线程之间会共享主存,因此非原子操作极容易出现类似于DB的“脏读”情况。A线程把某变量从主存读到工作内存准备修改,B线程立马就把主存的变量值改了,此时A线程工作内存中的变量便成了脏数据。

因此Java提供了Volatile关键字,通过保障可见性从而保证最终数据的一致性。

总结

为了保障数据一致性,不同的场景下有不同的技术手段。

作为开发人员,一方面需要理解数据一致性的概念,另一方面也可以结合工作或兴趣专门学习某种一致性的技术实现。

技术最终是服务于现实世界,因此技术理念大多也是基于现实场景而产生,理解技术理念时不应局限在纯技术中。

猜你喜欢

转载自blog.csdn.net/myle69/article/details/80153008