今天我们来讨论分布式数据复制。
为什么需要数据复制
我们在上一篇文章中谈到了分布式数据的分片存储技术,其核心在于将原数据划分为多个数据子集,然后将每个子集分散到不同的集群节点上存储,以实现负载均衡。那么,这里其实是有一个问题的。由于每个节点上面的数据完全没有交集,假设其中一个节点挂了,那么这个节点上的数据就丢失了。所以,我们需要一种技术方案,在数据分片的基础上,实现分布式集群的高可用性与可靠性,这就是我们今天要讨论的分布式数据复制技术。
数据复制是什么
数据复制就是一种数据备份技术。比如现在有集群节点1,那么我们会启用节点2,将节点1上的数据拷贝到节点2上,这样节点1与节点2上的数据完全相同。当节点1挂了的时候,可以立即启用节点2,继续对外提供数据存取服务,实现了分布式存储系统的自动容错。
数据复制的几种方案
要想节点2能够完全代替节点1进行工作,那么节点2必须要与节点1上的数据一致。但是这个一致性也要分强弱。我们接下来回顾一下CAP理论。
P就是指在集群中网络出现故障的时候,集群内的网络就被隔离开了(分区),但是必须能够对外正常提供服务。所以,由于分布式系统中的网络故障不可避免,P是必须满足的,否则就退化成了单机系统。另一方面,这条原则就让我们必须将数据分散到多个物理节点上,才能在某一条网络链路出现故障的时候,让副本节点顶上来,对外继续正常提供服务,这也就是我们为什么要做数据冗余备份与数据复制。
但是CAP理论又告诉我们,只能满足CP(偏一致性)或者AP(偏可用性)。那么,为什么CAP不能同时满足呢?假设我们就要满足CP,各节点间实现强一致性。那么,假设我对其中一个节点进行写操作,那么这个写操作就会一直阻塞等待,直到将更新后的数据同步到另一个节点上才会返回写操作成功。返回之后,才可以进行后续的读请求。这样保证了无论读哪个节点,数据都是一致的。但是,由于我们在复制完成之前一直会阻塞,会导致写操作等待时间较长,这样就损失了一部分可用性。所以,CAP是不可能同时满足的。像支付这种场景可能会追求CP(一致性),而电商这种场景更追求AP(可用性)。
基于以上分析,就可以引出我们三种不同的数据复制方案:
- 同步复制技术,注重一致性;
- 异步复制技术,注重可用性;
- 半同步复制技术,介于前两者之间。
接下来我们以数据库主从同步为例,逐一讨论。
同步复制技术
同步复制技术保证的是各节点之间的数据强一致性,所以,像我们刚才说的那样,在数据库读写分离时,用户更新数据的请求会打到主数据库节点上。主数据库必须要同步到备数据库之后才可给用户返回,即如果主数据库还没有同步到备数据库,用户的更新操作会一直阻塞。这种方式保证了数据的强一致性,但牺牲了系统的可用性,即CP。
这种方案适用于对数据一致性有严格要求的场合,比如金融、交易之类的场景。
异步复制技术
异步复制技术主要保证可用性,各节点之间容忍暂时的数据不一致,保证最终一致性即可。所以当用户请求更新数据时,主数据库处理完请求后可直接给用户响应,而不必等待备数据库完成同步,即备数据库会异步进行数据的同步,用户的更新操作不会因为备数据库未完成数据同步而导致阻塞。这种方式保证了系统的可用性,但牺牲了数据的一致性,即AP。
MySQL 集群默认的数据复制模式,采用的就是异步复制技术。我们主要关注两个关键的组件:binlog与relay log。
既然是异步,那么我们直接在主节点上执行完就可以返回了,让备数据库获取我们的更新内容,自己去做同步就好了,不用那么着急。所以,我们需要找个地方记下来做了什么操作,这里binlog就派上用场了。MySQL会往binlog中写入主数据库执行的所有更新操作,以便备数据库获取更新信息。然后备数据库专门启动一个IO线程读取binlog的内容,然后写入自己的relay log中。备数据库会有一个后台线程定期检查relay log的内容,一旦发现有更新,立即重放relay log,最终与主节点的数据达成一致:
这里我再额外提一下relay log,网上很多文章都没有说为什么要使用relay log。由于relay log是在从节点那一侧,那么从节点就可以在relay log上记录当前同步的进度并做各种标记。就相当于把公共资源复制了一份据为己有,我就可以基于这份复制的东西为所欲为了。而如果没有relay log,直接去读取并重放binlog的话,就没法实现了。此外,读取binlog并直接重放bionlog这个过程,相比直接拷贝binlog的内容到relay log这种方案,多了一个重放这个步骤,这就要多占用很多主从节点之间网络连接的时间资源,导致性能下降。所以,这就是为什么要使用relay log。
异步复制技术大多应用在对用户请求响应时延要求很高的场景。比如电商、秒杀这类场景。这时后台的数据库或缓存如果采用同步复制技术,用户可能就会因服务响应速度慢而崩溃,最终导致用户流失。因此这种场景最好采用异步复制技术,优先保证可用性。
半同步复制技术
半同步复制技术顾名思义,介于前两种方案之间。满足了一部分可用性及一致性。半同步复制技术主要应用在一主多从场景中。主节点不用等待所有备节点同步完毕就便可以响应写操作成功。也就是说,主节点可以等待一部分备节点同步完成后,就可以响应用户写操作执行成功。
而这里基于要等待多少个节点响应成功才算写操作成功,有细分为两种方案:
- 主节点收到一个备节点同步成功,就返回写操作成功;
- 主节点收到超过一半节点回复数据同步成功后,再给用户响应写操作成功。
这两种方案相对而言,第一种更偏向可用性,第二种更偏向一致性。在MySQL一主多备的场景下,一般采用的是第一种半同步复制技术。而Zookeeper则采用了第二种半同步复制技术。
实际上,多数的分布式存储系统与中间件,可以通过配置来选择不同的数据复制技术。我们根据我们自己的业务场景,选择合适的数据复制方案即可。
下期预告
【分布式系统遨游】分布式高可靠之负载均衡
关注我们
欢迎对本系列文章感兴趣的读者订阅我们的公众号,关注博主下次不迷路~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。