分布式数据
扩展至更高的载荷
共享磁盘架构(shared-disk architecture),它使⽤用多台具有独⽴处理器和内存的机器,但将数据存储在机器之间共享的磁盘阵列上,这些磁盘通过快速网络连接。这种架构⽤于某些数据仓库,但竞争和锁定的开销限制了共享磁盘方法的可扩展性
无共享架构
虽然分布式无共享架构有许多优点,但它通常也会给应⽤用带来额外的复杂度,有时也会限制你可用数据 模型的表达力。在某些情况下,⼀个简单的单线程序可以比一个拥有超过100个CPU核的集群表现得更好【4】。另一⽅面,⽆共享系统可以⾮常强大。接下来的⼏章,将详细讨论分布式数据会带来的问题
复制 vs 分区
复制提供了冗余:如果⼀些节点不可用,剩余的节点仍然可以提供数据服务。复制也有助于改善性能。
将⼀个大型数据库拆分成较小的子集
复制
如果复制中的数据不会随时间⽽改变,那复制就很简单:将数据复制到每个节点⼀次就万事⼤吉。复制的困难之处在于处理复制数据的变更(change),这就是本章所要讲的。我们将讨论三种流⾏的变更复制算法:单领导者(single leader),多领导者(multi leader)和⽆领导(leaderless)。⼏乎所有分布式数据库都使⽤这三种⽅法之⼀。
领导者与追随者
- 副本之⼀被指定为领导者(leader),也称为 主库(master) ,⾸要(primary)。当客户端要向数据库写⼊时,它必须将请求发送给领导者,领导者会将新数据写⼊其本地存储。
- 其他副本被称为追随者(followers),亦称为只读副本(read replicas),从库(slaves),次要( sencondaries),热备(hot-standby) 1 。每当领导者将新数据写⼊本地存储时,它也会将数据变更发送给所有的追随者,称之为复制⽇志(replication log)记录或变更流(change stream)。每个跟随者从领导者拉取⽇志,并相应更新其本地数据库副本,⽅法是按照领导者处理的相同顺序应⽤所有写⼊。
- 当客户想要从数据库中读取数据时,它可以向领导者或追随者查询。 但只有领导者才能接受写操作(从客户端的⻆度来看从库都是只读的)。
同步复制与异步复制
因此,将所有从库都设置为同步的是不切实际的:任何⼀个节点的中断都会导致整个系统停滞不前。实际上,如果在数据库上启⽤同步复制,通常意味着其中⼀个跟随者是同步的,⽽其他的则是异步的。如果同步从库变得不可⽤或缓慢,则使⼀个异步从库同步。这保证你⾄少在两个节点上拥有最新的数据副本:主库和同步从库。 这种配置有时也被称为半同步
设置新从库
- 在某个时刻获取主库的⼀致性快照(如果可能),⽽不必锁定整个数据库。⼤多数数据库都具有这个功能,因为它是备份必需的。对于某些场景,可能需要第三⽅⼯具,例如MySQL的innobackupex 【12】。
- 将快照复制到新的从库节点。
- 从库连接到主库,并拉取快照之后发⽣的所有数据变更。这要求快照与主库复制⽇志中的位置精确关联。该位置有不同的名称:例如,PostgreSQL将其称为⽇志序列号(log sequence number,LSN),MySQL将其称为⼆进制⽇志坐标(binlog coordinates)。
- 当从库处理完快照之后积压的数据变更,我们说它赶上(caught up)了主库。现在它可以继续处理主库产⽣的数据变化了。
处理节点宕机
从库恢复:追赶恢复
主库失效:故障切换
- 确认主库失效。有很多事情可能会出错:崩溃,停电,⽹络问题等等。没有万⽆⼀失的⽅法来检测出现了什么问题,所以⼤多数系统只是简单使⽤超时(Timeout):节点频繁地相互来回传递消息,并且如果⼀个节点在⼀段时间内(例如30秒)没有响应,就认为它挂了(因为计划内维护⽽故意关闭主库不算)。
- 选择⼀个新的主库。这可以通过选举过程(主库由剩余副本以多数选举产⽣)来完成,或者可以由之前选定的控制器节点(controller node)来指定新的主库。主库的最佳⼈选通常是拥有旧主库最新数据副本的从库(最⼩化数据损失)。让所有的节点同意⼀个新的领导者,是⼀个共识问题,将在第9章详细讨论。
- 重新配置系统以启⽤新的主库。客户端现在需要将它们的写请求发送给新主库(将在“请求路由”中讨论这个问题)。如果⽼领导回来,可能仍然认为⾃⼰是主库,没有意识到其他副本已经让它下台了。系统需要确保⽼领导认可新领导,成为⼀个从库。