分享

架构师之路,分布式架构下数据库一致性常用方法初探

 AnonymousV脸 2019-05-02

我们都知道绝大多数的互联网的应用都是读多写少的应用,我们也经常使用一主多从这样的模式,一是可以提高性能,二是多了一个数据备份,提高了程序的可用性。

主从数据库如何保持数据一致性,一直都是分布式系统一个值得探讨的问题,也几乎是BAT后台开发必问的面试题。我们今天就来讲一讲,如何保持分布式系统下数据库一主多备的数据一致性。

问题的由来

上图就是我们最常使用的数据库主备模型,这个模型有什么问题呢?我们不凡假设存在这么一个场景,用户收藏了一个商品,又立马刷新的数据库,这个时候后台再去读写从库的数据,如果数据还没有同步到,就会发现自己怎么还没有收藏这个商品。觉得程序bug了。

方案一:

最笨的方法,就是强制读读主库的数据了,对于一些update操作后重新读比较多的场景,我们强制要求读主库,或者在更新DB后立马返回主库更新后的结果,减少更新后立马读取数据的业务场景。

这种架构模型我们几乎就不用担心数据一致性的问题了,当然,如果主数据宕机了,从数据库可能还没同步都最新的数据,这就造成了数据丢失了。

这种方法的优点是操作简单,逻辑简单,缺点也是非常明显那就是从数据库完全成为一个备库,对性能上没有丝毫的帮助。为了提升性能,我们只能业务进行缓存了。

方案二:

利用数据库的半同步复制。以Mysql为例,Mysql为我们提供了好几种不同的主从数据库同步方式,如:

全同步复制:指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。很明显,全同步的效率太低了。假设又一个从库,写主库需要话200ms的时间,那么,使用全同步复制的话一个请求会至少需要400ms+的时间(双倍的写时间加上一定的TCP往返时间)。

异步复制:MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。这个会造成可能主库已经写完了,但是从库的数据还没有同步,读到的可能是旧数据。另外一方面,如果某个时间主DB宕机了,那么从库还没有同步到最新的数据。

半同步复制:介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。这是一个相对折衷的方案,我们来看看这个东西是怎么实现。

业务方提交一个写操作给数据库,主数据库写完记录后,commit成功后,会像从库发起写bin log的请求,因为写日志的数据实际上非常的快,写完就返回,相当于一次写操作要多一次tcp的往返时间。

事实上,从主库返回成功,到备库异步提交成功,还是有一定的时间差,不过这个时间相对于异步复制,已经大大减少了。

方案三:

使用数据库中间件进行路由,由数据库中间件进行路由。

一般的做法是我们的数据库中间件维护一个cache,我们预估好数据库主从同步的时间,例如200ms,如果某个key在200ms里面更新过,那么就读取主库的数据,否则就读从库的数据。除此之外,我们也会维护一定的数据缓存,在Update的时候,同时把主库的数据select出来,放在缓存中,加快数据库的读取速度。

这种方案就相对与前面两种,又更进了一步,但是改造成本更大了。好了,今天分布式的数据库主从一致性我们就讲到这里。想知道阿里巴巴是怎么做的么?想知道微信是怎么做的么?欢迎关注我,后面我们会继续分析。大家共同学习,共同进步。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多