乐趣区

构建可扩展的PostgreSQL解决方案

来源 | 愿码 (ChainDesk.CN) 内容编辑
愿码 Slogan | 连接每个程序员的故事
网站 | http://chaindesk.cn

愿码愿景 | 打造全学科 IT 系统免费课程,助力小白用户、初级工程师 0 成本免费系统学习、低成本进阶,帮助 BAT 一线资深工程师成长并利用自身优势创造睡后收入。
官方公众号 | 愿码 | 愿码服务号 | 区块链部落
免费加入愿码全思维工程师社群 | 任一公众号回复“愿码”两个字获取入群二维码

本文阅读时长:11min
可伸缩性是指软件系统随着使用它的业务增长而增长的能力。PostgreSQL 提供了一些功能,可以帮助您构建可扩展的解决方案,但严格来说,PostgreSQL 本身是不可扩展的。它可以有效地利用单台机器的以下资源:

它使用多个 CPU 内核通过并行查询功能更快地执行单个查询
如果配置正确,它可以使用所有可用内存进行缓存
数据库的大小不受限制; 创建多个表空间时,PostgreSQL 可以使用多个硬盘; 通过分区,可以同时访问硬盘,从而加快数据处理速度

但是,当涉及将数据库解决方案扩展到多台计算机时,它可能非常有问题,因为标准 PostgreSQL 服务器只能在单个计算机上运行。在本文中,我们将介绍 PostgreSQL 中不同的扩展方案及其实现。
系统可扩展性的要求意味着现在支持业务的系统也应该能够以与其增长相同的服务质量来支持相同的业务。
假设一个数据库可以存储 1 GB 的数据,并且每秒有效地处理 100 个查询。如果随着业务的发展,处理的数据量会增长 100 倍?它能够每秒支持 10,000 个查询并处理 100 GB 的数据吗?也许不是现在,不是在同一个装置中。但是,可以扩展可扩展的解决方案,以便能够在需要时立即处理负载。
在需要获得更好性能的场景中,设置更多服务器以处理额外负载并从主服务器将相同数据复制到它们是很常见的。在需要高可用性的情况下,这也是将数据连续复制到备用服务器的典型解决方案,以便在主服务器崩溃时它可以接管。
可扩展的 PostgreSQL 解决方案

复制可用于许多扩展方案。其主要目的是在系统出现故障时创建和维护备份数据库。对于物理复制尤其如此。但是,复制也可用于提高基于 PostgreSQL 的解决方案的性能。有时,第三方工具可用于实现复杂的扩展方案。
扩展以进行大量查询
想象一下,有一个系统应该处理大量的读取请求。例如,可能有一个应用程序实现支持网站上的自动完成功能的 HTTP API 端点。每次用户在 Web 表单中输入字符时,系统都会在数据库中搜索名称以用户输入的字符串开头的对象。由于用户数量众多,查询数量可能非常大,并且还因为每个用户会话都处理了多个请求。为了处理大量请求,数据库应该能够使用多个 CPU 核心。如果同时请求的数量非常大,则处理它们所需的核心数量可能大于单个机器可能具有的核心数量。
这同样适用于应该同时处理多个重度查询的系统。您不需要大量查询,但是当查询本身很大时,使用尽可能多的 CPU 将提供性能优势,尤其是在使用并行查询时。
在这种情况下,一个数据库无法处理负载,可以设置多个数据库,设置从一个主数据库到所有数据库的复制,使每个数据库作为热备用,然后让应用程序查询不同的数据库不同的要求。应用程序本身可以是智能的,每次都可以查询不同的数据库,但这需要应用程序的数据访问组件的特殊实现,如下所示:

另一个选择是使用一个名为 Pgpool-II 的工具,它可以作为几个 PostgreSQL 数据库前面的负载均衡器。该工具公开了一个 SQL 接口,应用程序可以连接到那里,就好像它是一个真正的 PostgreSQL 服务器。然后 Pgpool-II 会将查询重定向到当时执行最少查询的数据库; 换句话说,它将执行负载平衡:

另一种选择是将应用程序与数据库一起扩展,以便应用程序的一个实例将连接到数据库的一个实例。在这种情况下,应用程序的用户应该连接到许多实例中的一个。这可以通过 HTTP 负载平衡来实现:

数据分片
当问题不是并发查询的数量,而是数据库的大小和单个查询的速度时,可以实现不同的方法。可以将数据分成多个服务器,这些服务器将并行查询,然后将查询结果合并到这些数据库之外。这称为数据分片。
PostgreSQL 提供了一种基于表分区实现分片的方法,其中分区位于不同的服务器上,而另一个分区(主服务器)将它们用作外部表。在主服务器上定义的父表上执行查询时,具体取决于 WHERE 子句和分区的定义,PostgreSQL 可以识别哪些分区包含所请求的数据,并且只查询这些分区。根据查询,有时可以在远程服务器上执行联接,分组和聚合。PostgreSQL 可以并行查询不同的分区,这将有效地利用多台机器的资源。完成所有这些后,可以在应用程序连接到单个数据库时构建解决方案,该数据库将根据要查询的数据在不同的数据库服务器上物理执行查询。
也可以在使用 PostgreSQL 的应用程序中构建分片算法。简而言之,应用程序可能会知道哪些数据位于哪个数据库中,只在那里写入,并且只能从那里读取数据。这会给应用程序增加很多复杂性。
另一种选择是使用市场上可用的基于 PostgreSQL 的分片解决方案或开源解决方案。它们有各自的优点和缺点,但常见的问题是它们基于 PostgreSQL 的早期版本,并且不使用最新的功能(有时会提供自己的功能)。
最受欢迎的分片解决方案之一是 Postgres-XL,它使用运行 PostgreSQL 的多个服务器实现无共享架构。该系统有几个组成部分:
· 多个数据节点:存储数据
· 单个全局事务监视器(GTM):管理集群,提供全局事务一致性
· 多个协调器节点:支持用户连接,构建查询执行计划,并与 GTM 和数据节点交互
Postgres-XL 实现与 PostgreSQL 相同的 API,因此应用程序不需要以任何特殊方式处理服务器。它符合 ACID,这意味着它支持事务和完整性约束。该 COPY 命令也受支持。
使用 Postgres-XL 的主要好处如下:

它可以扩展以通过添加更多数据节点来支持更多读取操作
它可以扩展以通过添加更多协调器节点来支持更多写入操作
Postgres-XL 的当前版本(在撰写本文时)基于 PostgreSQL 10,它相对较新 Postgres-XL 的主要缺点是它不提供开箱即用的任何高可用性功能。当更多服务器添加到群集时,任何服务器失败的可能性都会增加。这就是为什么你应该注意备份或实现数据节点本身的复制。

Postgres-XL 是开源的,但可以获得商业支持。
值得一提的另一个解决方案是 Greenplum。它被定位为大规模并行处理数据库的实现,专门为数据仓库而设计。它有以下组件:
· 主节点:管理用户连接,构建查询执行计划,管理事务
· 数据节点:存储数据并执行查询
Greenplum 还实现了 PostgreSQL API,应用程序可以连接到 Greenplum 数据库而无需任何更改。它支持事务,但对完整性约束的支持是有限的。该 COPY 命令受支持。
Greenplum 的主要好处如下:

它可以扩展以通过添加更多数据节点来支持更多读取操作。
它支持面向列的表组织,这对于数据仓库解决方案非常有用。
支持数据压缩。
开箱即用支持高可用性功能。可以(并且建议)添加辅助主服务器,以便在主服务器崩溃时接管。还可以向数据节点添加镜像以防止数据丢失。

缺点如下:

它不能扩展以支持更多的写入操作。一切都通过单个主节点,添加更多数据节点不会使写入更快。但是,可以直接从数据节点导入文件中的数据。
它的核心使用 PostgreSQL 8.4。Greenplum 在 PostgreSQL 基础代码中添加了许多改进和新功能,但它仍然基于一个非常旧的版本; 但是,该系统正在积极开发中。
Greenplum 不支持外键,并且对唯一约束的支持是有限的。

Greenplum 有商业和开源版本。
扩展许多连接
与可伸缩性相关的另一个用例是当数据库连接的数量很大时。但是,当在具有大量微服务的环境中使用单个数据库并且每个数据库都有自己的连接池时,即使它们不执行太多查询,也可能在数据库中打开数百甚至数千个连接。每个连接都消耗服务器资源,只是处理大量连接的要求已经成为问题,甚至不执行任何查询。
如果应用程序仅在需要查询数据库并在之后关闭它们时才使用连接池和打开连接,则可能会出现另一个问题。建立数据库连接需要时间 – 而不是太多,但是当操作数量很大时,总开销将是巨大的。
有一个名为 PgBouncer 的工具可以实现连接池功能。它可以接受来自许多应用程序的连接,就像它是 PostgreSQL 服务器一样,然后打开有限数量的数据库连接。它将为多个应用程序的连接重用相同的数据库连接。建立从应用程序到 PgBouncer 的连接的过程比连接到真实数据库要快得多,因为 PgBouncer 不需要初始化会话的数据库后端进程。
PgBouncer 可以创建多个连接池,它们可以在以下三种模式之一中工作:
· 会话模式:与 PostgreSQL 服务器的连接用于与 PgBouncer 的客户端连接的生命周期。这种设置可用于加速应用程序端的连接过程。这是默认模式。
· 事务模式:与 PostgreSQL 的连接用于客户端执行的单个事务。当仅同时执行少量翻译时,这可用于减少 PostgreSQL 端的连接数。
· 语句模式:数据库连接用于单个语句。然后将它返回到池中,并为下一个语句使用不同的连接。此模式类似于交易模式,但更具侵略性。请注意,使用语句模式时,无法进行多语句事务。
可以设置不同的池以在不同模式下工作。
可以让 PgBouncer 连接到多个 PostgreSQL 服务器,从而起到反向代理的作用。
可以使用 PgBouncer 的方式如下图所示:

PgBouncer 建立了与数据库的多个连接。当应用程序连接到 PgBouncer 并启动事务时,PgBouncer 会为该应用程序分配现有数据库连接,将所有 SQL 命令转发到数据库,然后将结果传回。交易完成后,PgBouncer 将断开连接,但不关闭它们。如果另一个应用程序启动事务,则可以使用相同的数据库连接。这样的设置需要配置 PgBouncer 以在事务模式下工作。
PostgreSQL 提供了几种实现复制的方法,这种方法可以维护来自另一个服务器或服务器上的数据库的数据副本。这可以用作备份或备用解决方案,以便在主服务器崩溃时接管。通过使负载可以分布在多个数据库服务器上,复制还可用于提高软件系统的性能。

退出移动版