【CSDN 编者按】在本文作者将分享为什么最初选择了 Postgres RDS 作为我们的大数据解决方案,以及在使用过程中遇到的一些问题和挑战。文章还将分析 Postgres RDS 的优点和缺点,以及它与其他数据库产品的比较。最后,总结最终放弃 Postgres RDS 的原因,以及转向新的技术栈和架构。如果你也在考虑使用 Postgres RDS 作为你的大数据解决方案,那么这篇文章可能会对你有所帮助。
链接:https://medium.com/@mkremer_75412/why-postgres-rds-didnt-work-for-us-and-why-it-won-t-work-for-you-if-you-re-implementing-a-big-6c4fff5a8644
我们的初创公司主要业务是通过统计归因模型评估营销成效,这需要收集大量的在线用户行为数据,包括每次点击、每次字段输入和每项操作。这些数据存储在 PostgreSQL 数据库中,用户通过我们的界面运行仪表板和报告,这些数据量很大,给我带来很多技术挑战。我们开发的是一款多租户的 SaaS 应用,能够实现数据的按租户隔离,支持数百个租户的数据摄取和存储,这就要求系统具备良好的可扩展性和高性能。起初,我们选择了 AWS RDS 托管的 PostgreSQL 作为解决方案。
在 EBS 上,准确衡量吞吐量几乎是不可能的。AWS 提供的是延迟和 IOPS 指标,但这些都不足以衡量吞吐量。例如,当你需要扫描一个大型时间序列表(如 2000 万行,大小约 10GB)时,无论出于何种原因,你都需要一个准确的吞吐量指标来判断扫描整个表所需的时间。
如前所述,类似的查询很快会耗尽 IO 信用。面对需要更多 IOPS 的情况,一个直接的解决方案是增加存储容量,以便将基线 IOPS 从3000提高到 10000。然而,这会导致备份成本增加,因为你需要为整个卷支付费用,而不仅仅是已使用的部分。这样一来,成本增加了,但性能提升却有限,从而引发了成本和性能的雪球效应。
此外,我们还尝试增加实例大小,以便获得更多的缓存内存。如果能将所有数据都载入内存,理论上可以让数据库运行得更快。虽然 PostgreSQL v10 带来的更大并行化功能充满诱惑,但遗憾的是,由于 IO 的限制,我们实际收益不大。
关于测量吞吐量问题的更多细节,可以参见下面的链接:https://www.datadoghq.com/blog/aws-ebs-latency-and-iops-the-surprising-truth/
因此,我们决定迁移到 Aurora,它相比于传统 PostgreSQL,承诺提供 5 至 7 倍的性能提升,这一点对我们有非常强的吸引力。这些性能提升指标基于 pgbench 测试结果,在测试 PostgreSQL 性能时确实有效。如果你运营一个 OLTP 系统,并期望在有大量并行客户端的情况下测量事务速度(或延迟),pgbench 是一个很好的工具。但对于那些处理大数据集和进行数据挖掘操作的场景,pgbench 并不是一个理想的性能评估指标。这会带来是成本的上升。
关于 IOPS 和计费 IOPS 的讨论详见:https://forums.aws.amazon.com/message.jspa?messageID=835303#835303。
我们面临的最大挑战仍然是无法准确测量吞吐量。简单地通过计算扫描数据量与所需时间的比率(使用 track_io_timing)来进行评估时,我们意识到在处理大数据集时的性能远不如预期的 SSD 速度,实际上更接近于传统硬盘的速度。
更令人挫败的是,我们不得不花费大量时间来处理技术支持问题。尽管支持团队非常专业且乐于助人,问题的解决最终总是归结于调整查询或修改数据库配置。我真心希望能直接得到“考虑到你的工作负载,这项服务可能不适合你”的直接建议,但最终我们还是自己找到了解决方案。
对我们而言,解决方案非常明确:放弃使用托管数据库服务,转而在 EC2 上自行搭建基础设施。
我们通过选择等级较低的 EC2 实例来实现这一点,之前我们在 RDS 上使用的是 4XL 规格的实例,现在主要使用 xl 和 2xl 规格。
关键策略是利用 WAL-G(https://github.com/wal-g/wal-g)来分离主节点上的读写工作负载和实时更新的备份副本。
写入节点的速度可以稍慢,因为其主要任务是数据摄取,而 EBS 的性能对此已经足够。但我们通过使用 ZFS 对 EBS 进行压缩,实现了双倍的吞吐量。
对于读取节点,我们采用了配备临时 NVMe 驱动器的配置,并通过 ZFS 进一步提升了性能。
其结果显而易见:
费用从 ,000 降至 ,100(这是我们完全摆脱 RDS 依赖后第一个月的预估)。
原本需要数小时甚至无法完成的查询,现在只需几秒钟。
我们可以使用 Unix 实例上的命令行工具(例如 zpool iostat)来准确测量吞吐量。
虽然只需要单击按钮就可以启动一个实例,不必担心备份和恢复的便利性很诱人,但无论是从金钱还是性能的角度来看,这种便利是有代价的。如果你追求处理 TB 级或 GB 级数据的速度,那么使用裸机服务器是最佳选择,若不可行,则选择配备 NVMe 驱动器的 EC2 实例是第二选择。
本文引发广大网友的热议,下面是几个非常有代表性的观点:
作者的经验是有价值的,但不一定适用于所有的场景和需求。Postgres RDS 可能对于一些 OLTP 系统或者小型数据集合是一个合适的选择,但对于大规模的数据分析或者数据挖掘任务,可能需要更高效的解决方案。
作者没有充分利用 Postgres 的一些特性和优化方法,比如索引,分区,物化视图,压缩,异步提交等。这些技术可以提高 Postgres 的性能和可扩展性,减少 IO 压力和成本。
作者没有考虑使用其他的数据库或者数据仓库,比如 Redshift,Snowflake,BigQuery,ClickHouse 等。这些产品都是专门为大数据分析而设计的,提供了更快的查询速度,更低的存储成本,更灵活的扩展能力。
作者的迁移过程是有风险的,可能导致数据丢失,不一致,或者不可用。在迁移之前,应该做好充分的测试,备份,和监控,以确保数据的完整性和安全性。
你是否有更多不同的看法,欢迎在评论区留言讨论。