我们都知道,数据库在计算机应用中有着举足轻重的作用。为什么我们需要数据库,这个问题并不难回答,因为我们的很多数据需要进行持久化,并且需要高效地进行存储,并且可以快速读取,数据要保持准确,不同机器也要保持一致性。我们都知道,是机器就可能会出问题,并且还可能伴随着网络、电网等多种不可抗力因素,这年头,像支付宝被挖断光纤的事情,几乎每年就会出现好几起。今天,我们来聊一聊数据库的一些事情。我们常常使用分布式,也就是多机方案来解决上述问题,最简单的方法,我们可以使用一台备机,将主数据库的数据同步过去,这个时候,所有的业务系统仍然读写主数据库,从数据库只做冷备处理。
这种模型非常地简单,部署起来也非常的简单,并且,由于我们的业务系统都是读写同一个数据库,所以,在正常情况下,没有存在数据不一致的问题。当然,缺点也是非常地明显,那就是从数据库完全沦为冷备,除非在主库无法使用的情况下,否则从数据库只能是一个备胎。造成极大地浪费,另外一个方面,主从之间同步是有延迟的,在主备切换的时候,可能会有少量的数据丢失。另外一个问题,上述的主备模型只能够增加系统的容灾,不仅不能提升性能,反而因为主库需要同步数据到备库,会对性能有所消耗。那么,我们为什么不把备库利用起来呢?于是,有了数据库读写分离的方案,在主库上进行数据写入,在从库上进行数据读取,就好比有一条马路,原来机动车与非机动车都一起行驶,相当混乱,于是我们规定一个车道为非机动车道,行人在上面行走,而机动车只能在机动车道行驶,从而保证了马路的秩序。既然有了多个数据库,那么我们自然就会涉及到一个问题,数据库的同步,我们以Mysql为例,介绍几种常见的数据库同步方式。
全同步复制:指当主库执行完一个事务,之后发指令给所有的从库,让从库都执行相同的指令,执行成功之后,才返回给客户端,指令执行成功。这么做的优点是可以保证数据的强一致性,不过很明显,全同步的效率太低了。因为所有的请求都需要双倍的写入时间,假如原本一个写请求需要30毫秒,现在最少需要60毫秒了。这种只适合多读极少写要求数据强一致的业务场景。异步复制:MySQL默认的复制即是异步复制的,主库在执行完客户端提交的事务后会立即将结果返给给客户端。主库再负责把对应的命令分发给从库进行执行,很显然,这个会造成可能主库已经写完了,但是从库的数据还没有同步,读到的可能是旧数据。另外一方面,如果某个时间主DB宕机了,那么从库还没有同步到最新的数据。半同步复制:介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relaylog中才返回给客户端。这是一个相对折中的方案,我们来看看这个东西是怎么实现。
业务方提交一个写操作给数据库,数据库写完记录之后,