不同方案的比较
不同高可用方案的比较¶
-
共享磁盘故障转移
共享磁盘故障转移避免了只使用一份数据库拷贝带来的同步开销。它使用一个由多个服务共享的单一磁盘阵列。如果主数据库服务失效,后备服务则可以挂载并启动数据库,就好像它从一次数据库崩溃中恢复过来了。这是一种快速的故障转移,并且不存在数据丢失。
共享硬件功能在网络存储设备中很常见。也可以使用一个网络文件系统,但是要注意的是该文件系统应具有完全的POSIX行为(见网络文件系统的使用)。这种方法的一个重大限制是如果共享磁盘阵列失效或损坏,主要和后备服务都会变得无法工作。另一个问题是在主要服务运行时,后备服务永远不能访问共享存储。
-
文件系统(块设备)复制
共享硬件功能的一种修改版本是文件系统复制,在其中对一个文件系统的所有改变会被镜像到位于另一台计算机上的一个文件系统。唯一的限制是该镜像过程必须能保证后备服务有一份该文件系统的一致的拷贝,特别是对后备服务的写入必须按照主控机上相同的顺序进行。DRBD是用于Linux 的一种流行的文件系统复制方案。
-
预写式日志传送
温备和热备服务能够通过读取一个预写式日志(WAL)记录的流来保持为当前状态。如果主服务失效,后备服务拥有主服务的几乎所有数据,并且能够快速地被变成新的主数据库服务。这可以是同步的或异步的,并且只能用于整个数据库服务。
可以使用基于文件的日志传送(日志传送后备服务)、流复制(见流复制)或两者的组合来实现一个后备服务。关于热备的信息可见热备。
-
逻辑复制
逻辑复制允许数据库服务发送数据修改流给另一台服务。SeaboxSQL的逻辑复制从WAL中构建出一个逻辑数据修改流。逻辑复制允许复制个体表中的数据更改。逻辑复制不要求特定的服务作为主服务或者复制机,而是允许数据以多方向流动。更多有关逻辑复制的信息,请参考逻辑复制。通过逻辑解码接口(逻辑解码),第三方扩展也能提供类似的功能。
-
基于触发器的主-备复制
一个主-备复制设置会把所有数据修改查询发送到主服务。主服务异步地将数据修改发送给后备服务。当主服务正在运行时,后备服务可以回答只读查询。后备服务对数据仓库查询是一种理想的选择。
Slony-I是这种复制类型的一个例子。它使用表粒度,并且支持多个后备服务。因为它会异步更新后备服务(批量),在故障转移时可能会有数据丢失。
-
基于语句的复制中间件
通过基于语句的复制中间件,一个程序拦截每一个 SQL查询并把它发送给一个或所有服务。每一个服务独立地操作。读写查询必须被发送给所有服务,这样每一个服务都能接收到任何修改。但只读查询可以被只发送给一个服务,这样允许读负载在服务之间分布。
如果查询被简单地且未经修改地广播,
random()
、CURRENT_TIMESTAMP
之类的函数以及序列在不同服务上可能有不同的值。这是因为每一个服务会独立地操作,并且SQL查询被广播(而不是真正被修改的行)。如果这不可接受,中间件或应用必须从一个单一服务查询这样的值并且然后将那些值用在写查询中。另一个选项是将这个复制选项和一种传统主-备设置一起使用,即数据修改查询只被发送给主服务并且通过主-备复制传播到后备服务,而不是通过复制中间件。必须要注意的是,所有事务要么在所有服务上都提交,要么在所有服务上都中止,也许可以使用两阶段提交(PREPARE TRANSACTION和COMMIT PREPARED)。Pgpool-II和Continuent Tungsten是这种复制类型的例子。 -
异步多主控机复制
对于不会被定期连接的服务(如笔记本或远程服务),保持服务间的数据一致是一个挑战。通过使用异步的多主控机复制,每一个服务独立工作并且定期与其他服务通信来确定冲突的事务。这些冲突可以由用户或冲突解决规则来解决。Bucardo是这种复制类型的一个例子。
-
同步多主控机复制
在同步多主控机复制中,每一个服务能够接受写请求,并且在每一个事务提交之前,被修改的数据会被从原始服务传送给每一个其他服务。繁重的写活动可能导致过多的锁定,进而导致很差的性能。事实上,写性能通常比一个单一服务还要糟。读请求可以被发送给任意服务。某些实现使用共享磁盘来减少通信负荷。同步多主控机复制主要对于读负载最好,尽管它的大优点是任意服务都能接受写请求,没有必要在主服务和后备服务之间划分负载,并且因为数据修改被从一个服务发送到另一个服务,不会有非确定函数(如
random()
)的问题。SeaboxSQL不提供这种复制类型,尽管在应用代码或中间件中可以使用SeaboxSQL的两阶段提交(PREPARE TRANSACTION和COMMIT PREPARED)来实现这种复制。
表 高可用、负载均衡和复制特性矩阵总结了上述多种方案的能力。
表 高可用、负载均衡和复制特性矩阵
特性 | 共享磁盘故障转移 | 文件系统复制 | 预写式日志传送 | 逻辑复制 |
---|---|---|---|---|
最通用的实现 | NAS | DRBD | 内建流复制 | 内建逻辑复制,pglogical |
通信方法 | 共享磁盘 | 磁盘块 | WAL | 逻辑解码 |
不要求特殊硬件 | • | • | • | |
允许多个主控机服务 | • | |||
无主服务负载 | • | • | • | |
不等待多个服务 | • | with sync off | with sync off | |
主控机失效将永不丢失数据 | • | • | with sync on | with sync on |
复制体接受只读查询 | with hot | • | ||
每个表粒度 | • | |||
不需要冲突解决 | • | • | • |
特性 | 基于触发器的主-备复制 | 基于语句的复制中间件 | 异步多主控机复制 | 同步多主控机复制 |
---|---|---|---|---|
最通用的实现 | Londiste,Slony | pgpool-II | Bucardo | |
通信方法 | 表行 | SQL | 表行 | 表行和行锁 |
不要求特殊硬件 | • | • | • | • |
允许多个主控机服务 | • | • | • | |
无主服务负载 | • | |||
不等待多个服务 | • | • | ||
主控机失效将永不丢失数据 | • | • | ||
复制体接受只读查询 | • | • | • | • |
每个表粒度 | • | • | • | |
不需要冲突解决 | • | • |
有一些方案不适合上述的类别:
-
数据分区
数据分区将表分开成数据集。每个集合只能被一个服务修改。例如,数据可以根据办公室划分,如伦敦和巴黎,每一个办公室有一个服务。如果查询有必要组合伦敦和巴黎的数据,一个应用可以查询两个服务,或者可以使用主/备复制来在每一台服务上保持其他办公室数据的一个只读拷贝。
-
多服务并行查询执行
上述的很多方案允许多个服务来处理多个查询,但是没有一个允许一个单一查询使用多个服务来更快完成。这种方案允许多个服务在一个单一查询上并发工作。这通常通过把数据在服务之间划分并且让每一个服务执行该查询中属于它的部分,然后将结果返回给一个中心服务,由它整合结果并发回给用户。Pgpool-II具有这种能力。同样,也可以使用PL/Proxy工具集来实现这种方案。