立即开始为您的 PostgreSQL 加速。
作者:Juan José Gouvêa 和 Ana Tavares
随着数据以空前的速度不断增长,全球各地的企业都在努力寻找更有效的方式来管理和利用数据。根据国际数据公司 (IDC) 的报告,“数据圈”规模(对每年将创建的数据量的预测)预计到 2026 年将翻番。
数据量的激增给存储和数据库系统带来了巨大压力,需要不断提高可扩展性。随着云计算的出现,数据库管理系统已经发展到令人印象深刻的规模,通常存储数 TB 或更多的数据。这种趋势在短期内不会消失,尤其是在公司和其他组织采用数据驱动策略并深入研究分析以进行决策的情况下。
为了应对数据增长的挑战,企业必须采用能够有效管理数据的现代存储解决方案。PostgreSQL 是一种经过实战检验的关系型数据库管理系统 (RDBS),经过 30 多年的发展,在全球开发者中越来越受欢迎,能够应对这一挑战吗?
在 Timescale,我们认为答案是“可以”,但您需要在扩展 PostgreSQL 时采取正确的方法。
扩展 PostgreSQL 以适应快速增长的数据量,会带来一些挑战。尽管 PostgreSQL 灵活且快速,但它最初并非旨在应对当今数据规模的爆炸式增长,正如我们在关于PostgreSQL TOAST 的这篇文章中所论述的。
让我们概述一下扩展 PostgreSQL 数据库时遇到的主要障碍。
PostgreSQL 可以处理大量数据摄取速率,能够插入大型数据集(例如,每秒约 100K 行)。但是,这些速率仍然有限,随着数据摄取需求的增长,这个限制可能会成为需要实时高容量数据输入的应用程序的瓶颈。
当 PostgreSQL 中单个表的规模不断增长时,它可能会显著降低查询响应时间。对 100K 行进行排序与对 5000 万行进行排序之间的性能差异很大。这种变慢不仅会影响查询性能,还会影响数据库操作的效率,例如更新、删除和维护任务。
-- Example query sorting a small table
SELECT * FROM small_table ORDER BY column ASC;
-- Example query sorting a large table
SELECT * FROM large_table ORDER BY column ASC;
在上述示例中,对 large_table
的操作会由于数据量的增加而变得明显更慢,说明了表大小对性能的影响。
PostgreSQL 的架构旨在通过批处理和缓存来提高计算效率。但是,这种方法在处理和更新缓存数据的连续性方面引入了限制。
PostgreSQL 中的物化视图提供了一种将查询结果以类似表的形式缓存到表中的方法,这可以提高对频繁执行的查询的访问速度。但是,物化视图中的数据并不总是最新的,需要完全刷新才能更新,这使得它不太适合需要实时数据的应用程序。
-- Creating a materialized view
CREATE MATERIALIZED VIEW sales_summary AS
SELECT seller_no, invoice_date, sum(invoice_amt)::numeric(13,2) as sales_amt
FROM invoice
WHERE invoice_date < CURRENT_DATE
GROUP BY seller_no, invoice_date;
-- Refreshing a materialized view
REFRESH MATERIALIZED VIEW sales_summary;
REFRESH MATERIALIZED VIEW
操作对于大型数据集来说可能代价高昂,需要对视图进行完全重新计算。这个过程限制了处理连续性和维护实时数据的新鲜度。
所描述的挑战强调了这样一个事实,即虽然 PostgreSQL 是一款功能强大且通用的数据库系统,但要将其扩展以满足现代应用程序和数据量的需求,需要仔细规划和实施最佳实践。
解决这些挑战涉及利用 PostgreSQL 的功能,例如分区和复制,以及考虑架构更改,例如分片或采用其他技术更有效地分发工作负载。
有效地扩展 PostgreSQL 需要结合针对特定需求量身定制的策略。让我们来了解一下这些策略。
要优化摄取速率,请考虑将数据批处理成块,最好每插入一次在 50K 到 100K 行之间。这种方法利用了 PostgreSQL 在有效处理批量数据方面的优势。但是,对于处理时间序列数据的系统来说,数据流入速率非常高,这种方法本身可能不足。批处理的插入语句示例如下
INSERT INTO mytable (timestamp, metric1, metric2)
VALUES
('2022-06-01 12:00:00', 1, 1.11),
('2022-06-01 13:00:00', 2, 2.21);
随着数据的增长,存储成为一个关键问题。大型表不仅会占用大量存储空间,而且维护成本也很高。PostgreSQL 提供数据压缩机制来缓解这种情况,但会以访问速度为代价。因此,设计有效的压缩策略对于在存储成本和性能需求之间取得平衡至关重要。
索引 对于提高 PostgreSQL 中的查询性能至关重要。通过加速数据检索,它们可以显著加快查询速度。但是,创建和管理索引需要深入了解数据和访问模式,因为它们也会增加数据库的存储空间占用。 PostgreSQL 支持多种索引类型,包括 B 树、哈希、GiST、SP-GiST、GIN 和 BRIN,每种索引类型都针对不同类型的查询进行了优化。
将大型表分成较小的块可以显著提高查询性能,尤其是在查询针对数据特定部分时。 PostgreSQL 支持范围、列表和哈希分区,允许灵活的分区策略。按日期对表创建范围分区的示例如下
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
物化视图可以缓存查询结果,并使用新数据对其进行增量更新。对于在相同数据集上重复运行的查询,这种策略特别有效。但是,设置和维护增量更新可能会很复杂。
实现只读副本 可以分发查询负载,从而提高数据库的读取能力。只读副本是主数据库的同步副本,用于为主数据库分流读取查询。这种方法需要仔细管理同步过程,以确保数据一致性。
对于难以应对时间序列数据扩展需求的数据库, Timescale 能够为 PostgreSQL 增强性能,使其能够应对苛刻的工作负载,并提供针对时间序列数据优化的自动扩展解决方案。它简化了许多传统的扩展挑战,提供针对时间序列模式而设计的有效数据存储、压缩和分区的内置机制。
在本节中,我们将深入探讨 Timescale 如何解决常见的 Postgres 扩展问题,包括数据摄取、存储优化、索引策略、表分区、连续聚合和读取扩展,所有这些都通过代码示例和文档提供支持。 有关 Timescale 工作原理的更多信息,请访问我们的文档。
Timescale 利用 PostgreSQL 的架构提供高摄取速率,能够协调多个摄取过程。这允许将摄取操作分解成并行进程,每个进程可以处理大约每秒 100K 次插入。该策略侧重于最大限度地利用硬件和网络资源,展示了一种类似于命令模式的模式,例如
-- Pseudo code to demonstrate parallel ingest pattern
BEGIN;
INSERT INTO conditions (time, location, temperature) VALUES (NOW(), 'office', 70.0);
COMMIT;
这种方法强调使用 PostgreSQL 的高效插入机制,同时利用 TimescaleDB 的能力将这些操作分发到多个后台工作进程中。
Timescale 引入了分层存储和列式压缩来应对存储空间挑战
分层存储:实现一种系统,根据访问频率将数据存储在不同的存储介质上。这种策略对于管理数据集生命周期中的成本和性能至关重要。
列式压缩:TimescaleDB 的时间索引设计简化了列级压缩,通常在没有显著性能下降的情况下实现高达 10 倍的压缩率。
例如,在超表上配置压缩可以像以下一样简单:
SELECT add_compression_policy('conditions', INTERVAL '7 days');
此命令为七天之前的旧数据启用自动压缩,显著减少存储需求。
Timescale 自动处理时间序列数据的索引过程,无需您进行大量规划和实施自定义索引策略。例如,创建一个基于时间和位置的索引可能如下所示:
CREATE INDEX ON conditions (time DESC, location);
此索引通过利用时间序列数据的固有时间排序特性以及任何其他维度(例如位置)来提高查询性能。
超表是 Timescale 的核心功能,它可以将时间序列数据自动划分为可管理的块。这种分区沿两个维度进行——时间和一个可选的附加属性,从而实现高效的数据管理和查询优化。
SELECT create_hypertable('conditions', 'time', 'location', chunk_time_interval => INTERVAL '1 week');
超表创建自动执行数据分区,通过维护更小、更易于管理的数据集来提高数据摄取和查询性能。
连续聚合提供了一种强大的方法,可以维护对大型数据集的实时增量视图,从而显著减少聚合查询的计算负载。
CREATE VIEW conditions_summary WITH (timescaledb.continuous) AS
SELECT time_bucket('1 day', time), AVG(temperature)
FROM conditions
GROUP BY 1;
此功能允许对聚合数据进行高效的查询性能,并在新数据到达时无缝更新。
Timescale 通过创建和管理 读取副本 来促进读取扩展,从而将查询负载分布到多个实例。这对于高可用性设置以及将分析工作负载与事务处理分离至关重要。
-- Hypothetical command to add a read replica
SELECT add_read_replica('service_id', 'replica_configuration');
此命令将为服务添加一个读取副本,从而提高读取能力和系统弹性。
通过重新设计 Postgres 最受欢迎的一些功能并引入新的功能,Timescale 将 Postgres 变成一个可扩展的时间序列数据管理解决方案,可以解决开发人员在处理大量数据时面临的核心挑战。最棒的是,您不会被陡峭的学习曲线所拖累:您仍然可以使用您熟悉和喜爱的丰富可靠的 Postgres 生态系统。
在当今数据密集型环境中扩展 PostgreSQL 会带来独特的挑战,从摄取限制到管理大型表以及确保高效的查询性能。尽管 PostgreSQL 为用户提供了扩展工具,但有效利用这些功能需要对数据库系统及其管理的特定数据工作负载都有深刻的了解。
Timescale 凭借其旨在增强 PostgreSQL 原生功能的解决方案套件(尤其针对时间序列数据),简化了数据摄取、存储优化和实时分析的复杂性,使您能够更有效地扩展 PostgreSQL 系统。
亲身体验 TimescaleDB 的功能和优势:免费试用 Timescale,无需信用卡.