美文网首页开源
pg高可用和负载均衡方面的各方案对比

pg高可用和负载均衡方面的各方案对比

作者: robot_test_boy | 来源:发表于2020-09-17 22:35 被阅读0次

    数据库服务器可以一起工作, 如果主数据库服务器失效则允许一个备服务器快速接手(高可用性), 或者可以允许多个数据库服务器提供相同的数据(负载均衡)。理想情况下, 数据库服务器能够无缝地一起工作。 提供静态网页服务的网页服务器可以非常容易地通过把网页请求均衡到多个机器来组合。 事实上,只读的数据库服务器也可以相对容易地组合起来。不幸的是, 大部分数据库服务器收到的请求是读/写混合的,并且读/写服务器难于组合。 尽管只读数据只需要在每台服务器上放置一次, 但对于任意服务器的一次写动作却必须被传播给所有的服务器, 这样才能保证未来对于那些服务器的读请求能返回一致的结果。

    这种同步问题是服务器一起工作的最根本的困难。 因为没有单一解决方案能够消除该同步问题对所有用例的影响。有多种解决方案, 每一种方案都以一种不同的方式提出了这个问题, 并且对于一种特定的负载最小化了该问题所产生的影响。

    某些方案通过只允许一台服务器修改数据来处理同步。 能修改数据的服务器被称为读/写、主控或主要服务器。 跟踪主控机中改变的服务器被称为后备或第二服务器。 如果一台后备服务器只有被提升为一台主控服务器后才能被连接, 它被称为一台温后备服务器, 而一台能够接受连接并且提供只读查询的后备服务器被称为一台 热后备服务器

    某些方案是同步的, 即一个数据修改事务只有到所有服务器都提交了该事务之后才被认为是提交成功。 这保证了一次故障转移不会丢失任何数据并且所有负载均衡的服务器将返回一致的结果 (不管哪台服务器被查询)。相反, 异步的方案允许在一次提交和它被传播到其他服务器之间有一些延迟, 这产生了切换到一个备份服务器时丢失某些事务的可能性, 并且负载均衡的服务器可能会返回略微陈旧的结果。当同步通信可能很慢时, 可以使用异步通信。

    方案也可以按照它们的粒度进行分类。某些方案只能处理一整个数据库服务器, 而其他的允许在每个表或每个数据库的级别上进行控制。

    在任何选择中,都必须考虑性能。通常在功能和性能之间都存在着权衡。例如, 在一个低速网络上的一种完全同步的方案可能使性能减少超过一半, 而一种异步的方案产生的性能影响可能是最小的。

    共享磁盘故障转移:只能主备

    共享磁盘故障转移避免了只使用一份数据库拷贝带来的同步开销。 它使用一个由多个服务器共享的单一磁盘阵列。如果主数据库服务器失效, 后备服务器则可以挂载并启动数据库,能从一次数据库崩溃中恢复过来了。 这是一种快速的故障转移,并且不存在数据丢失。

    共享硬件功能在网络存储设备中很常见。也可以使用一个网络文件系统NFS, 但是要注意的是该文件系统应具有完全的POSIX行为。 这种方法的一个重大限制是如果共享磁盘阵列失效或损坏, 主要和后备服务器都会变得无法工作。另一个问题是在主要服务器运行时, 后备服务器永远不能访问共享存储。

    文件系统(块设备)复制

    共享硬件功能的一种修改版本是文件系统复制, 对一个文件系统的所有改变会被镜像到位于另一台计算机上的一个文件系统。 唯一的限制是该镜像过程必须保证后备服务器有一份该文件系统的一致的拷贝 — 特别是对后备服务器的写入必须按照主控机上相同的顺序进行。 DRBD是用于 Linux 的一种流行的文件系统复制方案。

    预写日志传送

    温备和热备服务器能够通过读取一个预写日志(WAL)记录的流来保持为当前状态。如果主服务器失效, 后备服务器拥有主服务器的几乎所有数据, 并且能够快速地被变成新的主数据库服务器。预写日志记录流可以是同步的也可以是异步的, 并且只能用于整个数据库服务器。

    可以使用基于文件的日志传送、 流复制或两者的组合来实现一个后备服务器。

    逻辑复制

    逻辑复制允许数据库服务器将数据修改流发送到另一台服务器。 PostgreSQL逻辑复制从WAL构造一个逻辑数据修改流。 逻辑复制允许复制单个表中的数据更改。逻辑复制不需要将特定服务器指定为主服务器或副本, 但允许数据在多个方向上流动

    基于触发器的主-备复制

    一个主-备复制设置会把所有数据修改查询发送到主服务器主服务器异步地将数据修改发送给后备服务器。当主服务器正在运行时, 后备服务器可以回答只读查询。后备服务器对数据仓库查询是一种理想的选择。

    Slony-I是这种复制类型的一个例子。它使用表粒度, 并且支持多个后备服务器。因为它会异步更新后备服务器(批量), 在故障转移时可能会有数据丢失。

    基于语句的复制中间件

    基于语句的复制中间件,一个程序拦截每一个 SQL 查询并把它发送给一个或所有服务器。 每一个服务器独立地操作。读写查询必须被发送给所有服务器这样每一个服务器都能接收到任何修改但只读查询可以被只发送给一个服务器, 这样允许读负载在服务器之间分布。

    如果查询被简单地且未经修改地广播,random()、 CURRENT_TIMESTAMP之类的函数以及序列在不同服务器上可能有不同的值。 这是因为每一个服务器会独立地操作,并且 SQL 查询被广播(而不是真正被修改的行)。 如果这不可接受,中间件或应用必须从一个单一服务器查询这样的值并且将那些值用在写查询中。 另一个选项是将这个复制选项和一种传统主-备设置一起使用, 即数据修改查询只被发送给主服务器并且通过主-备复制传播到后备服务器, 而不是通过复制中间件。必须要注意的是,所有事务要么在所有服务器上都提交, 要么在所有服务器上都中止,也许使用两阶段提交(PREPARE TRANSACTION 和COMMIT PREPARED)。Pgpool-II 和Continuent Tungsten是这种复制类型的例子。

    异步多主控机复制

    对于不会被定期连接的服务器(如笔记本或远程服务器), 保持服务器间的数据一致是一个挑战。通过使用异步的多主控机复制, 每一个服务器独立工作并且定期与其他服务器通信来确定冲突的事务。 这些冲突可以由用户或冲突解决规则来解决。Bucardo 是这种复制类型的一个例子。

    同步多主控机复制

    在同步多主控机复制中,每一个服务器能够接受写请求,并且在每一个事务提交之前, 被修改的数据被从原始服务器传送给每一个其他服务器。 繁重的写活动可能导致过多的锁定,进而导致很差的性能。事实上, 写性能通常比一个单一服务器还要糟。读请求可以被发送给任意服务器。 某些实现使用共享磁盘来减少通信负荷。同步多主控机复制主要对于大多数读负载是最好的, 尽管它的大优点是任意服务器都能接受写请求 — 没有必要在主服务器和后备服务器之间划分负载, 并且因为数据修改从一个服务器发送到另一个服务器, 不会有非确定函数(如random())的问题。

    PostgreSQL不提供这种复制类型, 尽管在应用代码或中间件中可以使用PostgreSQL的两阶段提交 (PREPARE TRANSACTION和COMMIT PREPARED) 来实现这种复制。

    商业方案

    因为PostgreSQL是开源的并且很容易被扩展, 一些公司已经使用PostgreSQL并且创建了带有唯一故障转移、 复制和负载均衡能力的商业性的闭源方案。

    相关文章

      网友评论

        本文标题:pg高可用和负载均衡方面的各方案对比

        本文链接:https://www.haomeiwen.com/subject/fkfkyktx.html