目前我有一个网站,有一台 Postgres 数据库服务器。它只供少数用户使用(少于 10 个),但它需要尽可能长的正常运行时间。
我希望数据库具有某种自动故障转移功能。
所以我当时想的是:一台服务器运行 PGPool II,一台服务器运行 Postgres 作为主服务器,一台服务器运行 Postgres 作为从服务器。但是,如果 PGPool 运行的任何地方突然断电(或死机,或其他情况),就会出现单点故障,整个系统就会瘫痪。
假设无法将此外包给其他人,那么是否有解决方案?
答案1
有一件事是肯定的,那就是必须至少有两台机器在运行pgpool
。如何实现这一点取决于——没有一种解决方案可以普遍适用于所有情况。如果你有一个 Web 应用程序,那么你还必须在至少两台机器上运行该 Web 应用程序,因此你可以这样做:
+----------+ +---------+
| pgmaster | | pgslave |
+----------+ +---------+
| |
+----------+-------------+-----------+
| |
+-----|----+ +-----|----+
| pgpool | | pgpool |
| | | | | |
| webapp | | webapp |
+-----|----+ +-----|----+
| |
internet internet
(在这种情况下,您还需要在客户端进行某种故障转移 - 我将其标记为“互联网”。)
另一方面,如果你真正需要的不是一个高可用性的 Web 应用程序(或类似的服务),而是一个高可用性的 Postgresql(任何客户端都可以随时连接),那么另一种选择是
+----------+ +---------+
| pgmaster | | pgslave |
+----------+ +---------+
| |
+----------+-------------+-----------+
| |
+-----|----+ +-----|----+
| pgpool | | pgpool | (standby)
+-----|----+ +-----|----+
| |
Failover
IP address
|
client
在这种pgpool
情况下, 也可以与数据库位于同一台机器上。重要的是,您需要某种 IP 地址故障转移,可以是keepalived
,但可用的确切解决方案取决于您使用的数据中心的较低级别的网络详细信息(例如,keepalived
无法在 Hetzner 中工作,因为他们有切换故障转移 IP 的不同方式)。还请注意,在这种情况下,连接的客户端可能将要在发生故障转移时断开连接,但他们将能够立即重新连接。
还要注意,还有其他困难,其中之一就是不能排除网络分区,即两台 PostgreSQL 机器都在工作并连接,但它们不知何故彼此失去了连接,所以它们各自都会认为对方已经死机,因此各自都会决定成为主服务器。为了解决这个问题,我知道三种解决方案:1) STONITH,这需要特殊的硬件;2) Quorums,这需要特殊的软件(例如 corosync/pacemaker);3) 手动故障转移(管理员会收到通知,系统会中断,直到他们决定如何修复它)。但是,如果您使用我上面提出的方案,设置法定人数可能并不太困难,但使用三个pgpool
s 而不是两个;但我不记得是否pgpool
支持这一点。
底线:高可用性可能很难实现,而且成本高昂。请仔细研究完全避免高可用性的可能性。如果做不到,请做好大量研究、大量设计、大量重新设计的准备,并意识到这将花费大量时间。