上一篇文章中,主要聊了下数据分片的主要内容,我们知道,**通过数据分片其实可以解决数据存储的高性能以及可拓展,但是也导致了用join和使用分布式事务进行查询和存储数据的问题,**属于按下葫芦浮起瓢。但是在分布式领域中,如果只存储一份数据,其实不能保证存储高可用,因此需要将数据进行存储多份保存。也就是数据镜像,而数据镜像的方式有很多,一主一从,一主多从,一主一备,一主多备。但是数据复制就会涉及到数据之间的拷贝,也就是数据一致性问题。你看这就是为了解决一个问题,引入了别的问题。架构权衡的艺术。
复制的话主要介绍下单主复制、多主复制、无主复制几种常见的数据复制方式。
复制
复制的主要好处
- 1.增加数据可用性和安全性:数据备份多个保证数据的可用性,即出现单点宕机数据可以恢复。
- 2.减少往返时间:基于复制的方式,可以将数据分布到不同的区域,用户访问最近的数据节点。可以大大缩短网络请求耗时。
- 3.增加吞吐量
复制的坏处 - 1.数据一致性问题
- 任何事物都有两面性,采用数据复制的方式,可以将数据存储到多个节点中,但是对于客户端来说是无感知的,数据修改(更新、删除、添加)都需要实时备份到其他节点,那么这个过程中因为网络是不可靠,可能出现数据同步不一致,那么为保证性能,需要放弃一些别的属性,比如返回过期数据
单主复制
单主复制的架构其实就是一主多从,其中有一个Leader或Master节点,有多个从节点,主节点提供读写服务,然后将数据同步到从节点,可以通过同步日志或者转发请求,而从节点提供读操作。
同步数据的方式主要是三种:同步复制、异步复制、半异步复制
同步复制
同步复制,其实就是主节点接受到数据变更的请求,同时将数据同步给从节点1、从节点2,当从节点1、2都更新成功的时候,在返回结果给客户端,客户端此时在请求任意一个节点,都可以获取一致的数据。但是缺点就是整个过程性能比较差,如果其中一个节点更新数据过慢,那么整个过程就比较耗时。
异步复制
异步复制,当主节点收到数据更新请求,会直接返回数据更新成功,然后异步线程更新数据到从节点1,从节点2。这样的话虽然性能上比较快,但是客户端访问从节点1、2可能数据这个时候还没有同步过来,可能读取到旧数据。
半同步复制
基于同步和异步复制,同步复制太慢,虽然数据一致性可以保证,但是异步复制快,但是数据一致性没有办法保证,所以半同步复制的原理就是将数据至少同步给2个节点,(主和从),这样即使出现主节点宕机之后,另一个从节点也可以选举成为一个新的leader节点。避免因异步复制而导致数据丢失。
那么如何选择呢?其实就看具体的业务场景,根据不同的场景,具体选择。
好了,这里总结以下,单主复制的优缺点
优点
- 1.简单易懂,比较好实现,对于客户端要么需要显示的使用主从节点,要么使用代理中间件,即可以将读写请求进行解析,将写请求到主节点,读请求分发到从节点。
- 2.不用处理多个主节点之间数据的关系,并且写操作只会落到主节点上,分布式事务也比较好实现。
- 3.大量的读请求,可以很好的实现可拓展。通过增加多个从节点来提升读的性能
缺点 - 1.只有一个主节点提供写服务,不能很好的拓展写请求服务。
- 2.当主节点宕机之后,系统的整体写请求不能处理,因此就会引入,选择哪些合适的节点成为主节点,选举问题? 选举出来之后,如何切换 手动切换&主动切换 ,分布式领域的脑裂问题?
应用场景
其实针对像MySQL,Redis 本身就提供了复制功能,MySQL支持上述三种方式,而Redis则通过复制 Redis Cluser模式提高系统的可用性。具体可以看 【Redis】聊一下Redis数据同步/复制 这里留一个坑,后续补一下MySQL的同步原理机制。
多主复制
为什么需要多主复制?
单主复制解决了数据读的压力,提供读性能,但是对于写请求来说也只能由一个主节点进行处理,所以为了提升写的性能很简单的方式就是通过多个主节点进行数据复制,即每个主节点都可以承担数据的写请求。
多主复制有哪些问题?
最直观的就是一个数据,可能同时被A、B两个主节点进行写入,这个时候如果出现网络问题,导致A延迟了,那么应该以那个数据为准,也就是出现了数据冲突。而比较麻烦的点,就是多主复制的问题。
解决方案?
1.客户端解决,一般可以将数据推送给客户端,用户自己选择,我在使用有道云比较的时候,有时候多个客户端操作同步文件,就会出现多个版本的文件,但是这个时候需要我自己来选择那个文件。
2.最后写入胜利 这种方式比较简单,也就是谁最后写入的,按照最后的为准,给每个写请求标记一个时间戳或者唯一自增ID
3.因果关系跟踪,根据使用一种因果关系的算法,推算出数据前后,比如用户先下单,在支付。
优缺点
优点:1.即使出现主节点宕机,其他主节点依然可以提供写请求服务。可以实现容错。 2.可以提升写请求的性能 3.用户可以将请求发送最近的节点,比如北京发送到北京的服务器,上海到上海的服务器。
缺点:数据冲突问题,比较难解决。
应用场景:
大多数业务场景其实不会使用这种方式,主要针对的是地理级别的数据中心,可以将用户数据存储在一个数据中心中。少用户与数据中心之间的网络延迟,提升用户体验
无主复制
这里简单介绍下无主复制,因为主从复制和多主复制都需要以来主节点进行数据的写入,而如果不采用主节点,每个节点都是主节点,那么就没有数据写入节点宕机的问题。所以大概就是数据写入的时候,同时将数据写入到多个节点 或者全部节点。而只要返回一定节点的数量成功,就认为数据写入成功。但是也会出现写入失败的情况,这个时候就需要依赖于数据修复能力。具体可以看下Quorum。