一、双主保证高可用MySQL数据库集群往往采用一主多从、主从同步、读写分离的方式来扩展数据库的读性能,保证高可用读取的数据库。但是此时写库还是单点。在MySQL数据库集群中,可以设置两个主库,设置双向同步,通过冗余写入的方式保证写入库的高可用。2.并发导致的不一致数据冗余会导致数据一致性问题,因为数据同步存在时间差,并发写入可能导致数据同步失败,导致数据丢失:如上图所示,假设主库使用autoincrement作为自增主键:两个mysql-master设置双向同步可以保证主库高可用库中已有记录的主键为1、2、3。主库1插入一条主键为4的记录,发送给主库。数据库2同步数据在数据同步成功之前,主数据库2也插入了一条记录。由于数据没有同步成功,插入记录生成的主键也是4,数据也同步到主库1,主库1和主库2都有一条主键为的记录插入了4,双主同步失败,数据不一致。3、步长相同能不能避免冲突,保证两个主库生成的主键一定不能冲突?答:设置不同的初始值和设置相同的增长步长就可以了。如上图所示:可以通过两个MySQL-master设置的双向同步来保证主库1库的高可用。数据库2插入数据的主键是1/3/5/7,数据库2插入数据的主键是2/4/6/8。双向同步无冲突的数据后,两个主数据库将包含所有数据。如上图所示,这两个主库最终会包含1/2/3/4/5/6/7/8的所有数据。即使一个主库宕机,另一个主库也能保证写库的高可用。4、上游生成ID,避免冲突换个思路,为什么要靠数据库的自增ID来保证数据的一致性呢?上游业务完全可以使用统一的ID生成器来保证ID不会产生冲突:如上图,调用方插入数据时,也可以通过引入全局***来解决这个问题ID而不是依赖于数据库的自增。至于如何生成一个有上升趋势的全局ID,请参考文章《分布式ID生成算法》。5、消除重写并不能治本。使用自增方式同时写入两个主库可能会导致数据不一致。只有一个主库用来提供服务,另一个主库作为shadow-master。它仅用于确保高可用性。可以避免一致性吗?那问题呢?如上图所示:可以通过两个MySQL-master设置的双向同步来保证主库的高可用。只有主库1对外提供写服务。两个主库设置相同的虚拟IP,主库1挂了。或者当网络异常时,虚拟IP会自动漂移,影主在上,保证主库的高可用。由于虚拟IP不变,切换过程对调用方是透明的,但在极端情况下,也可能会造成数据不一致:如上图所示:可以使用两个MySQL-master的双向同步来保证主库的高可用,设置相同的虚拟IP。一条记录,主键为4,数据同步到shadowmaster主库2,突然主库1网络异常。keepalived检测到异常后,实现虚拟IP漂移,主库2开始提供服务。在库2中插入了一条记录,同时也生成了一条主键为4的记录,导致数据不一致。6、内网DNS检测双主同步延迟导致的虚拟IP漂移和数据不一致。本质上,双主之后需要同步数据之后,实现虚拟IP偏移,使用内网DNS检测,实现shadowmaster延时高可用:使用内网域名连接数据库,例如:db.58daojia.org主库1和主库2设置双主同步,不使用同一个虚拟IP,分别使用ip1和ip2。一开始db.58daojia.org指向ip1。使用一个小脚本轮询ip1主库的连通性。当ip1的主库出现异常时,小脚本延迟x秒。延时,等待主库2同步数据,然后将db.58daojia.org解析为ip2程序重新连接内网域名,然后自动连接ip2主库,并保证数据的一致性七。总结主库的高可用,主库的一致性,一些tips:双主同步是保证写库高可用的常用方式。设置相同的步长和不同的初值可以避免自增产生冲突。主键不依赖于数据库和业务调用方自己生成全局***ID是个好办法。影主保证写库的高可用。只有一个写作库提供服务,不能完全完全保证一致性内网DNS检测可以实现在主库1出现问题后延迟一段时间,再切换主库保证数据一致性【本文为专栏作者《58深鉴》原创稿件,转载请联系原作者】点此阅读作者更多好文
