Master-slave 架构能够说是最经常使用的架构,关系型数据库诸如:mysql,postgreSql,oracle,Nosql诸如:MongoDb,消息队列诸如:Kafka,RabbitMQ等都使用了这种架构,本文将先简要介绍此种架构并介绍高可用Master-slave架构中的一些坑,以及应对之策。mysql
因此一般状况下,这种架构通常都是用彻底异步的方式进行同步,这种状况下,若是主库失效,那么全部尚未被复制的数据就可能会被丢失;可是若是从库失效,主库依然能够继续处理写入操做。web
主库会记录每一个请求的sql,而且将这些sql:insert select update等发送至从库执行,虽然听上去没什么问题,可是:redis
这种复制方法如今基本不太使用了。算法
以前说过,主库在处理写请求时,都会先写WAL(Write Ahead Log),日志的结构很是底层,包含了写入时须要追加的数据序列:磁盘块中哪些数据发生了更改。这就意味着它会比数据库存储结构紧密相关,甚至有可能数据库只由于版本不一致而致使没办法复制。sql
对于运维来讲,这点就很不友好了。若是复制协议对于版本不匹配的话,一般状况下须要停机才能够升级。数据库
另外一种方法是使用另外一种日志,只是这种日志再也不于底层存储耦合,好比Mysql的binlog。它通常是以行为密度来描述写入的操做:缓存
这种日志普遍应用,它包含的信息与底层彻底解耦,甚至能够基于它复制不一样数据库的数据。微信
若是咱们须要新增新的副本,如何保证新的从库拥有与主库彻底一致的数据呢?由于客户端在不断的向主库写入数据,最简单的办法,咱们能够禁止主库的写入,而后使用日志进行同步;但这会违背咱们高可用的原则。咱们通常使用以下方法:网络
首先每一个从库的硬盘上确定也会记录全部从主库收到的数据库的变动,若是从库挂了,等他恢复的时候能够从日志中知道发生故障以前最后处理的一个事物,接着链接主库,请求拉取全部以后它断片以后数据变动,以后追遇上主库便可架构
主库挂了须要fail over(故障转移):须要将一个新的从库提高为主库,而且从新配置应用客户端,将全部写操做发送到新的主库。一般有以下几个步骤:
一、确认主库失效。现实生活中有不少缘由致使失效:崩溃、停电、网卡以及机器被修空调的师傅搬走等缘由。没有万无一失的方法,大部分系统采用简单的超时来肯定。
二、选一个新的主库。主库的选举一般是以拥有着主库最新数据的那个从库为准,具体的算法能够是paxos raft等共识算法。
三、从新配置路由,写请求发送到新的主库上;而且若是老领导回来了,须要避免“脑裂”的状况,让老领导下台成从库。
failOver一样会有不少问题:
大部分web应用都是读多写少,因此咱们一般采用多副本异步复制的架构,基于异步架构,可能会致使数据库从库和主库的明显不一致,可是通过一段时间后,他们最终会是一致的。
正常状况下,复制延迟大概是几分之一秒,可是在极端的状况下(网络延迟,机器高负荷)延迟可能达到几秒甚至几分钟。
因此这是咱们在实际中会遇到的真实问题,了解这些问题以后能够帮助咱们更好的设计业务。问题体如今下面几个方面:
读写一致性的意思就是保证用户能够读到本身的写,可是不保证其它用户也能够及时的读到;其它用户可能须要延迟才能够读取到。保证读写一致性的话,有下面几个方向:
还有一种状况,好比用户有电脑和app端进行查询,电脑更新了信息如何保证手机上能够及时的查看到,如何保证读写一致性呢?有多台设备的话你没法记录末次更新的时间戳(由于手机不可能知道电脑末次操做的时间),不一样设备的时间自己也是不可靠的,这种状况,能够根据userID进行散列,保证同一个用户永远会落到一个Datacenter上的主库。
单调读的意思是时光倒流:
用户2345前一秒还能够查询出结果,后一秒数据就没有了。单调读是这种异常的保证机制,咱们须要保证同一个用户的查询请求老是被落到同一个follower上,好比说能够根据userid取模,散列到固定的机器上。
实际上数据库的操做能够分红因果操做和并发操做两种类型,并发操做能够理解为A发起set A操做,B发起set B操做,这两个操做是并发的没有前后因果关系的,数据库对于这种操做只须要确认发生的顺序就能够肯定最终的值;对于因果操做:A发起insert 666,B再发起update 666,这两个操做是有依赖关系的,A成功了B才能够成功。若是数据库先接受到B的请求,那么久发生冲突了。 这样的操做叫作因果操做。(下一章会详细讨论)
回到咱们的问题,若是要解决这类问题,首先咱们须要一个算法分辨出那些操做是并发的,那些操做是因果的;对于这种问问题再回答的典型的因果类型的操做,咱们应该尽可能让他们分配到同一个partition以内,确保有因果关系的写入到写到同一个分区。
本文讨论了典型的master-salve架构中常见的问题和解决的办法,某些概念尚未进行深刻研究,后续介绍多主、无主架构时再说明。
根据CAP原则,最终一致性是无可避免的,可是咱们能够作一些基于业务的特殊处理,在保证高可用的同时,尽可能去保证数据的一致性。