我已经设置了两台带有 PG Pool 的服务器来为 webapp 创建 HA 设置。
PGPool 和 postgres 在两台服务器上运行,使用从服务器 1 到服务器 2 的流式复制。每台机器上的 Web 应用连接到 PgPool,然后 PgPool 将请求发送到当前主服务器。它设置为在数据库连接中断时自动进行故障转移,运行自定义故障转移脚本将服务器 1 降级为从服务器,并将服务器 2 提升为主服务器。
今天早上发生的事情是,网络瘫痪了 2 分钟,这意味着两个 PGPool 实例无法相互通信 - 因此每个 PGPool 都认为另一台机器已瘫痪。
服务器 1 – 继续作为主服务器,断开服务器 2 的连接
服务器 2 – 启动故障转移,断开服务器 1 的连接,并使自己成为主服务器
由于网络中断,故障转移命令无法到达服务器 1 并将其设为从服务器,反之亦然。因此,当网络在 2 分钟后恢复时,我拥有的只是两台服务器,它们都认为自己是主服务器。
PgPool 似乎没有自动故障回复命令,该命令可用于在网络重新连接时强制服务器 1 再次成为主服务器,这是我能想到的唯一真正的解决方案。
我的问题是我应该如何处理这种情况?这是否是此设置的正确架构?当然,这是一种常见的情况,我不知道如何解决这种情况。
编辑:让 pgpool 在 linux-ha 下的虚拟 ip 下运行是否可取?可以解决问题,我已经在公共 IP 上启动并运行了它 - 这样,每台机器都只能访问一个 pgpool 实例。
答案1
首先,我认为 pgpool2 确实有一个故障回复命令,但在这种情况下这不会对你有多大帮助。问题是,如果两台机器都认为自己是主服务器,就会造成混乱。更重要的是,这里有一个简单的案例:网络中断。如果网络被分区怎么办?即两台机器都已连接,但它们不知何故彼此失去连接。在这种情况下,两台机器都将成为主服务器,它们将为不同的客户端提供服务,并且你将拥有一个分叉数据库。这是一种罕见的情况,但你确定这种情况不太可能发生,以至于你愿意冒由此产生的混乱的风险吗?
另一种方法是这样的:
+- master db
|
------ pgpool ------+
|
+- hot standby
但是,在这种情况下,您有一个单点故障,即 pgpool,这可能是您不想要的。我只知道两种解决这个问题的方法。最简单的方法是手动将备用服务器提升为主服务器,这适用于您的架构。您的应用程序将需要进入只读模式,直到人工干预。
第二种方法是使用法定人数。一种可行的架构如下:
+--- pgpool standing by -+ +- master db
| | |
failover ip -+--- active pgpool -+----+- hot standby 1
| | |
+--- pgpool standing by -+ +- hot standby 2
|
+- hot standby 3
(as many standby servers as
you want, so that you have
read-only load balancing)
三个 pgpool 运行在三台不同的机器上,每个都有自己的 IP 地址,但它们还提供一个额外的故障转移 IP 地址,仅由活动机器使用,并且它是客户端使用的 IP 地址。如果活动 pgpool 发生故障,备用 pgpool 将接管它。这可以通过 来实现heartbeat
。
为了将热备用提升为主服务器,法定数量的 pgpool(即三个中至少两个)必须做出决定;并且它们将在决定后延迟(例如 10 秒)后才执行该决定。此外,活动 pgpool 不得在未收到至少另一个 pgpool 的确认的情况下继续使用现有主数据库超过 10 秒(这是为了防止两个备用 pgpool 同时失去与活动 pgpool 和主服务器的连接,将热备用提升为主服务器,但活动 pgpool 继续使用旧主服务器)。
实际上,第三个 pgpool 不需要参与故障转移 IP,只需要在那里帮助仲裁即可。此外,我不知道 pgpool 是否有足够的功能来做到这一点。也许你需要另一个守护进程。更通用的架构是这样的:
+--- active pgpool -+ +- master db
| | |
failover ip -+ -+----------+- hot standby 1
| | |
+--- pgpool standing by -+ +---+- hot standby 2
| |
| +- hot standby 3
monitoring daemon 1 ---+ |
| |
monitoring daemon 2 ---+------+
|
monitoring daemon 3 ---+
在这种情况下,pgpool 完成的负载平衡与监控以及将备用服务器提升为主服务器是分开的。请注意,您可以将 pgpool、数据库服务器和监控守护程序放在同一台机器上,但两个 pgpool 必须位于两台不同的机器上,三个监控守护程序必须位于三台不同的机器上。请注意,我不知道是否存在具有所有必要功能的现成监控守护程序。
细节可以改变,但我认为,如果您在不使用法定人数的情况下自动将备用服务器提升为主服务器,那么您就是在自找麻烦。
答案2
这是否是此设置的正确架构?这当然是一种常见情况,我无法理解如何修复此类问题。
免责声明:我没有使用过 pgpool,但我知道它的作用。
在集群软件中,当集群只知道不到一半节点的状态时,您通常不希望发生任何可能违反并发规则的自动操作(例如,某项操作只能在一个地方在线)。这可以防止出现您所经历的裂脑情况。在双节点集群中,这意味着如果两个节点之间的网络互连中断,则不会发生自动故障转移。应由人工决定是否进行故障转移,并确认这是正确的操作,具体取决于“其他”节点是否离线,或者是否接受可能丢失未复制的事务。我不知道这是否是您可以在 pgpool 中配置的内容。
答案3
如果您的服务器位于同一个 LAN 中(彼此访问的网络延迟较低),您可以考虑以复制多主模式运行 pgpool。您需要同时更新两个数据库,这将带来一些开销。
如果一个系统发生故障,pgpool 可以通过活动节点继续提供访问。系统恢复后,你可以在 pgpool 中运行在线恢复来启动另一个节点。