建立一个主备强一致性的数据库系统

数据的一致性

数据库中有一个非常重要的技术,更新操作写日志。事务提交时,先写日志后写数据库,保证整个更新操作数据不丢失。因此,对于实现主备的一致性可以用同样的方案:

  1. 事务提交时,执行两个操作。一个是日志写主库的磁盘的操作,另一个是备库同步主库磁盘日志的操作。
  2. 两个操作的成功执行返回后,才返回给应用方,事务提交成功。

整个事务提交操作的逻辑图如下:

Imgur

高可用性

数据库的主备提供了一种容灾处理的方案:主库 Crash,备库提升为主库,对外提供服务。

为此需要引入一个调度器,进行容灾处理的主备切换。调度器部署在独立的服务器上,同时连接着主备,有定时的心跳检测。当其检测到主库无法连接时,就切换备库。(修改备库的 VIP 或 DNS 及一些列激活操作)。

调度器自身的可用性

为了解决 dispatch 的单点问题,引入 Paxos/Raft 等分布式强一致性算法解决。将一台 dispath 增加到多台 dispatch,通过 Paxos/Raft 选主逻辑进行选主

网络问题

调度器和数据库无法连接,可能是数据库故障,也有可能发生网络问题。那么如何识别出当前是网路问题还是主库 Crash 呢?

通过在数据库服务器上部署 dispatch client, 通过 client 使用租约的机制,主库上的 client 每隔一段时间向 dispatch master 续租主库当前的状态,并且在一定时间内收到 master 同意续租的确认,主库才不会降级为被库。

Imgur

因此,主库 crash,client 向 master 发送放弃租约的请求,master 收到请求后,提升备库为主库,对外提供服务;主库和 client 同时 crash,master 和 client 通讯失败,master 未收到续租请求,那么 master 将备库提升为主库,原主库重启为备库;client 和 master 网络出现问题,client 和 master 通讯失败,client 未收到 master 的确认续租的请求,将主库降为备库,master 未收到 client 的续租请求,将原备库作为主库。

基本到此为止,一个持续可用,分区可用性保证,主备数据强一致性的数据库系统就没问题了。

低延迟

那么如何保证高性能呢?

应用发起事务请求时,必须将事务的日志从主库中同步到从库中。主库和从库之间的网络,影响了同步的效率。一个简单的解决办法是增加多个 slave,只要一个 slave 同步完成后,事务就可以提交,极大地减少了某一个网络抖动造成的影响。同时也避免了从库的单点问题。

还有一个问题,当变成多副本后,主库 crash 后,diapatch master 如何选择从库,提升主库了。提供一个原则,日志最新的作为主库,日志都是最新的时候,选择 IP 地址小的。

Loading Disqus comments...
Table of Contents