Postgres 9.0和pgpool复制:单点故障



我的应用程序使用Postgresql9.0,由一个或多个与全局数据库交互的工作站组成:它就像一个常见的客户端-服务器应用程序,但为了避免任何额外的硬件,所有工作站都包括客户端和服务器:主站被提升为同时充当服务器,其他任何工作站都充当它的客户端。这个解决方案允许我进行扩展:用户最初可能需要一个站点,但它可以决定在未来扩展到更多站点,而在初始阶段不需要无用的单独服务器。

我正在努力避免,如果主站坏了,所有其他人都会停止工作;要做到这一点,最好的解决方案可能是将主数据库连续复制到一个或多个工作站上未使用的数据库。

通过搜索,我发现pgpool可以满足我的需求,但从所有示例和教程来看,故障点似乎从主数据库移动到运行pgpool的服务器。

我读了一些关于多pgpool和心跳工具的文章,但不清楚如何做到

考虑到我的体系结构,哪里不存在独立和专门的服务器,有人能给我一些提示吗?在故障转移的情况下,pgpool似乎是自动完成所有工作的,我可以认为故障转移情况可以由标准用户在没有管理员干预的情况下处理吗?

对于这类应用程序,我非常喜欢亚马逊的Dynamo设计。链接中的文档很大,但值得一读。事实上,有些应用程序已经实现了这种方法:

  • mongoDB
  • 卡桑德拉
  • 伏地魔计划

也许是其他人,但我不知道。卡桑德拉是从Facebook起家的,佛地魔是LinkedIn使用的。让事情变得分布式,并在数据分发中添加冗余,您将远离传统的主从复制方法。

如果您想继续使用PostgreSQL,那么实现这样的方法应该没什么大不了的。您将需要实现一个额外的层(代理),该层将根据预先配置的选项来决定如何检索/保存数据。

代理层可以实现在:

  • 申请(需要大量工作IMHO)
  • 数据库
  • 作为中间件

您可以在中间件层使用PL/Proxy,该项目起源于Skype。它被深度集成到PostgreSQL中,所以我认为它是选项2和选项3的组合。PL/Proxy将要求您对数据库的所有类型的查询使用函数。如果遇到性能问题,可以使用PgBouncer。

最后一点:无论你决定走哪条路,都需要已知的开发量。

编辑:

这完全取决于你们所说的"故障",以及你们认为系统处于中断状态的原因。

让我们看看pgpool的功能。

  1. 连接池PostgreSQL在每个会话中使用一个进程(fork)。显然,如果你有一个非常繁忙的网站,你会达到操作系统的限制。为了克服这个问题,使用了连接池。它们还允许您均匀地使用资源,因此通常在数据库之前设置pooler是个好主意
    在pgpool中断的情况下,您将面临大量客户端无法访问您的数据库。如果您将它们直接指向数据库,避免pooler,您将面临性能问题。

  2. 复制所有查询都将自动复制到从属实例。这对DML和DDL查询有意义
    在pgpool中断的情况下,您的复制将停止,从属服务器将无法赶上主服务器,因为pgpool之外没有进行更改跟踪(据我所知)。

  3. 负载平衡您的只读查询将分布在多个实例中,从而获得良好的响应时间,使您能够在系统上增加带宽
    在pgpool中断的情况下,如果系统能够处理这样的负载,那么查询的运行速度会突然慢得多。在这种情况下,master数据库将迎头赶上,而不是失败的pgpool。

  4. 限制超过连接pgpool将对连接进行排队,以防它们无法立即处理
    在pgpool中断的情况下,所有此类连接都将中止,这可能会中断DB/Application协议,即Application被设计为永远不会中止连接。

  5. 并行查询在多个节点上执行单个查询以减少响应时间
    在pgpool中断的情况下,这样的查询将不可能进行,从而导致更长的处理时间。

如果你能很好地面对这样的情况,并且你不把它们当作失败,那么pgpool可以很好地为你服务。如果5分钟的停机将使您的公司损失数千美元,那么您应该寻求更可靠的解决方案。

停机成本越高,故障切换系统就应该调整得越精细。通常,它不仅仅是用于实现故障切换自动化的单一工具。在每一次失败中,你都必须调整:

  • DNS,除非您希望重新配置所有客户端
  • 重新初始化备份和故障转移过程
  • 确保老主人不会试图为它的角色而战,以防它回来(STONITH)
  • 根据我的经验,我们是DBA、系统管理员、架构师和运营部门的人员,他们决定正确的策略

最后,在我看来,pgpool是一个很好的工具,我确实使用过它。但它并不是一个完整的故障转移解决方案,并非没有额外的思考、采取的措施和编写的脚本。因此,我提供了到分布式数据库的链接,它们提供了更高级别的可用性。

PostgreSQL由于其强大的可扩展性,可以毫不费力地实现分布式。

首先,我建议查看pgBouncer而不是pgpool。接下来,您试图达到什么级别的扩展?您可以选择在所有客户端系统上运行连接池(bouncer足够轻,可以运行)。

也就是说,维耶戈罗夫的答案可能是你在这个时代真正应该关注的方向。你确定你真的需要一个数据库吗?

编辑

因此,显而易见的答案是,如果只有一个盒子在运行,pgPool会创建一个单点故障。显而易见的解决方案是在多个盒子上运行多个池。然后,您需要设计应用程序代码来处理数据库断开连接。这听起来并不容易,但基本上您需要使用两阶段提交来进行非幂等更改。因此,在最大可能的范围内,您应该使您的更改成为幂等的。

根据您的评论,我想您在处理数据库复制方面的经验可能有限?pgPool执行基于语句的复制。这里有一些权衡。好处是它很容易设置。缺点是无法保证复制数据库上的数据是相同的。它也(我相信,但最近没有检查)与2pc不兼容。

我之前的评论是问你是否真的需要一个数据库,这是因为我认为你设计了一个系统,而没有详细介绍它的这一部分。我在类似系统的"这一部分"上有大约20年的工作经验。我希望你会发现,没有现成的解决方案,所涉及的问题会变得非常复杂。换句话说,我建议你重新考虑你的设计。

尝试阅读此博客(包含大量关于PostgreSQL和PgPool II的信息):

https://www.itenlight.com/blog/2016/05/21/PostgreSQL+HA+带+pgpool II+-+部件+5

在同一个博客上搜索"WATCHDOG"。有了它,您可以配置PgPool II集群。不过,需要同一子网上的两台机器,以及同一子网上的一个虚拟IP。

希望这对任何尝试同样事情的人都有用(即使这个答案已经晚了很多)。

PGPool当然会成为一个单点故障,但它比Postgres实例小得多。

虽然我还没有尝试过,但应该可以安装两台带有PGPool的机器,但只能在一台机器上运行。然后,如果主主机不可用,您可以使用Linux HA在备用主机上重新启动PGPool,并可以选择在主主机恢复时再次故障恢复。同时,您也可以使用Linux HA来移动单个虚拟IP,这样您的客户端就可以连接到一个用于Postgres服务的IP。

postgres服务器的死亡将使PGPool向备份postgres发送查询(如有必要,将其升级为master)。

PGPool服务器的死亡将导致短暂的停机(可配置,但可能在<1min的范围内),直到PGPool在待机状态下启动,IP地址被声明,并发送一个免费的ARP。当然,客户端必须足够聪明,才能在不死亡的情况下重新连接。

最新更新