来自 PostgreSQL 维基
跳转到导航跳转到搜索

云和 PostgreSQL

概述

本页面用于收集关于如何在“云”基础设施上大规模运行 Postgres 的信息,包括组织层面(具有多样化的应用程序)和基础设施层面(具有大量服务器)。首先,我们需要更好地定义“云”。

  • CPU/内存/块设备的组合不可靠,可能比机架中的物理硬件不可靠一个到两个数量级。
    • 在块设备的情况下,损坏不太可能发生,但可用性问题更有可能出现。
  • 配置机器相对可靠,并且可能比在机架中配置物理硬件容易三到四个数量级。
  • 不可变存储比块设备更可靠,可用性更高。
  • 以传统的“物理”级别来考虑设备变得更加复杂。
  • 提供者-消费者关系:为使经济上可行,相对较少的人员必须运行大量基础设施,并且必须将基础设施消费者和基础设施提供者之间之前比较模糊的某些交互类型明确化。

简而言之:在这样的环境中运行 Postgres 意味着利用配置的便利性,在提供者和消费者之间无需太多协调的情况下,即可提供可用性和性能。

块设备与不可变范围

到目前为止,弹性可用的块设备一直受到可用性和性能问题的困扰。这可能是因为提供具有(甚至可能没有)快照功能的弹性可附加/可分离块设备的问题相当困难。不可变存储比块设备更可靠,并且是灾难恢复和长期归档的理想选择。PostgreSQL 中成熟的 WAL 传输功能非常适合此场景,尽管像 pg_lesslog 这样的项目可能会非常有用。另一种选择是剥离索引 XLog 记录,并直接从堆中重建索引到已恢复的数据库。

此特定问题有很多影响:特别是,它在数据库大小和可用性之间建立了非常清晰的关系。小型数据库可以从不可变存储中快速下载并重播,大型数据库则无法如此快速地重建。这反过来又会影响有关容量规划和何时在应用程序中设计分区功能的决策:分区越大,其可用性就越差。

使用 EC2 和 S3 作为示例,计算数据库可用性的经验法则。

  • 要从头开始重建数据库,需要大约 5 分钟:大约需要 8GB 或更小。
  • 在 S3 上恢复 1GB 的成本在 30 秒到 1 分钟之间。
  • 恢复 1TB 的成本约为半天(12 小时)。
  • 压缩通常有很大帮助:在很多情况下,预计磁盘上显示的文件大小将减半甚至更多。
  • 压缩数据解压缩后,即使是 S3 的 0.2Gbit 速度也可能使 RAIDed EBS 块设备的顺序写入速度饱和,EBS 块设备的顺序写入速度已达到 0.8Gbit/s。预期:许多设备将通过以太网提供,而 1Gbit/s 是可以合理期望获得的理论最大值。

可能在以下几个类别中进行优化

  • 启用预取,将一些时间开销转移到可用性下降之前。
  • 减少通过网络或到磁盘传输的实际数据量。
  • 无需将整个数据库一次性地具体化到块设备上即可获得可用性。
  • 并行和分区恢复,以便能够使用更多网络和 I/O 资源来执行恢复。

提供者与消费者关注点分离

提供 Postgres 的基础设施提供商可能会至少承诺对正常运行时间和数据保留/备份/丢失提供软性保证(或者可能只是指导)。一般来说,基础设施提供商的消费者不希望与提供商通信,除非存在需要直接行动和干预的重大问题。此外,可以假设用户希望随时执行任何操作,这使得某些事情变得很困难。

以下是一些提供商的示例痛点

  • 可以随时发出的 DDL 会使某些任务变得更加困难。要求消费者在定期发生的时段内不要发出 DDL 噪音太大,因此,目前尚不清楚如何为 Postgres 作为一项服务提供逻辑复制解决方案。一般来说,缺乏强大的逻辑复制(或编写此类功能的能力)是一个严重的问题,原因有很多,包括 Postgres 版本升级。
  • VACUUM FULL:提供商通常根据低级物理资源收费,但 VACUUM FULL 采取的重锁使得无法回收资源。此外,不必要的大关系堆文件会延长从不可变存储中恢复所需的时间。最后,VACUUM 管理是消费者和提供者责任之间一个有点敏感和模糊的界限。理想情况下,提供者会在非异常情况下处理大多数 VACUUM 问题:大多数消费者在休闲使用条件下因膨胀而导致性能下降时,只会对服务感到沮丧。能够在不影响可用性的情况下运行 VACUUM FULL 会很有用。
  • REINDEX:缺乏“concurrently”选项对于在线减少索引膨胀来说是有问题的。可以通过 CREATE INDEX CONCURRENTLY 和重命名来解决,但此功能感觉最好能很好地集成到 DBMS 中。
  • 启用使用方便的 PostgreSQL 扩展,这些扩展可以使用非超级用户帐户成功执行 pg_dump/pg_restore。
  • 需要通过 postgresql.conf 执行的任何更改。在需要时,通过非特权用户 SQL 语句(或可能由提供者安装的 SECURITY DEFINER 垫片)可以很好地执行自助服务版本。某些日志设置属于此类。
  • 提供计划切换而不会丢失数据:如果提供商在执行任何内部维护任务时导致静默数据丢失,则可能会表现不佳。应用程序进程被告知连接已断开的偶发、非常短时间的可用性故障是可接受的。相比之下,在执行例如容量升级或降级以执行切换时,确认 COMMIT 后续丢失数据是不可接受的。消费者(合理地)认为这是一个容量变更功能,该功能存在一个静默丢失数据的错误,并且没有采取任何措施来解决它。

明确的示例,说明哪些肯定不在提供商的范围内

  • 代表消费者创建索引以使运行速度更快(注意:提供有关运行速度慢的内容的可视性 *是* 提供商的责任)。
  • 设计一个运行足够快的模式。

多租户

有很多小型消费者和数据库,或者具有动态工作负载需求的消费者。Postgres 本身并不是一个很好的多租户系统:噪音很大的邻居很难控制,并且许多功能(例如通过 WAL 复制移动单个消费者数据库)在同一个集群中存在多个数据库时无法正常工作。解决这些问题的工程挑战相当大,因此,轻量级容器化技术(如 LXC(Linux)、FreeBSD Jails 和 Solaris Zones)在提供物理级别的资源共享和利用方面变得越来越重要。最稀缺的系统资源是内存,系统的一个重要属性是启动速度(完全闲置的 Postgres 可以进入休眠状态并等待端口活动:参见 systemd)。

Postgres 已经很精简,启动速度很快(6MB 代码映像可以共享,即使是 LXC),但以下内容可能有用。

  • 在低活动数据库中,由 postmaster 定期分叉,而不是维护后台进程的持续活动。处于联机状态但没有连接且没有太多工作的数据库,理想情况下只有 postmaster 运行。
  • 动态、在线调整某些资源的大小,例如共享内存,以更优雅地应对具有多个租户的机器上的快速需求变化。
  • 全新 initdb 在磁盘上的大小。一些其他技巧(如 COW)可能不必在 Postgres 中执行,但这方面应该发布一种合理实用的方法。

后端状态

HA、切换和进程池由后端状态复杂化,这些状态很难被外部系统评估,尤其是存在于事务之外的状态。例如,大多数 Web 应用程序使用的常见 SQL 功能不依赖于任何事务间状态功能,但客户端偶尔会使用 WITH HOLD 游标、设置全局配置设置、利用 pg_advisory_lock、使用 dblink 或其他需要保留会话状态以获得合理行为的功能。其中一些状态可能很容易保存到表或其他共享数据结构中,以便进程可以在状态之间“上下文切换”,而另一些则可能无法保存。无论如何,这些功能通常很少用于大部分 OLTP 查询,但对交互式查询的资源密集型、延迟敏感(但通常在语义上并不复杂)的工作负载造成了很深的僵化性。