Amazon RDS for PostgreSQL等产品非常适合小型部署,但扩展 PostgreSQL 则是另一回事。一旦项目增长到许多 TB,这些托管数据库就会变得缓慢且昂贵,从而使数据管理变得更加复杂。
一旦表达到数十亿行,性能就会受到影响,而
但现在不再了。今天,我们很高兴地宣布分层存储全面上市,这是一种多层存储架构,旨在为 Timescale 平台中的时间序列和分析数据库提供无限、低成本的可扩展性。现在,您可以将较旧的、不经常访问的数据存储在低成本存储层中,同时仍然能够访问它,而无需牺牲经常访问的数据的性能。
当您使用我们新的多层存储后端将数据插入 Timescale 时间序列数据库时,会发生以下情况:
您的最新数据将被写入针对快速查询和高摄取进行优化的高性能存储层中。
一旦您不经常访问该数据,您可以通过设置分层策略自动将其分层到成本较低的对象存储层。低成本存储层中的数据在您的数据库中仍然完全可查询,并且您可以存储的数据量没有限制 - 高达数百 TB 或更多。我们的低成本存储层的数据统一价格为每 GB/月 0.021 美元,比 Amazon S3 便宜。
开发人员需要一种廉价的方法来扩展AWS中的大型 PostgreSQL 数据库,而不影响性能。虽然对象存储具有惊人的可扩展性和经济性,但它们并不是最快的,开发人员还需要为其应用程序获得毫秒级的查询响应。
然而,一旦数据变得陈旧并且很少被访问,实时性能通常就不那么重要了。开发人员仍然需要能够访问这些历史数据以进行临时查询、数据分析或法规遵从性,但他们可以假设这些类型的查询存在一定的延迟。现在,开发人员想要的是能够尽可能经济且高效地存储这些历史数据。
这种新的分层存储架构使开发人员无需在实时应用程序的存储成本和性能权衡之间进行选择。通过将最近和经常访问的数据保留在高性能层中,他们将利用 Timescale 的毫秒查询速度和摄取功能,并且通过对旧数据进行分层,他们可以在 PostgreSQL 数据库中保留所需数量的 TB较少的。
Timescale 的分层存储架构利用了 PostgreSQL 的灵活性和
这种存储架构还消除了 Timescale 服务中的任何存储限制:由于我们的低成本存储层是无限的,因此您可以存储任意数量的 TB。例如,
该 Insights 数据库不断收集和分析来自我们客户群体的查询统计信息,目前已超过 350 TB,并且还在快速增长。在这 350 TB 中,250 TB 分层为低成本存储。
让我们算一下:
压缩后,我们在高性能存储层中存储 5 TB。当然,我们启用了压缩,并且压缩率达到了 20 倍,这意味着通过压缩,原来 100 TB 的 Postgres 数据现在可以容纳在 5 TB 磁盘中(!)
剩余的 250 TB 数据存储在低成本存储层。一旦数据达到一定的年龄(目前为几周前),这种分层就会自动发生。
我们的大型部署客户也已经在使用分层存储:
“我们对市场数据进行了大量分析,而我们需要存储的数据量巨大,使得普通的基于磁盘的数据库解决方案不可行(成本太高)。Timescale 的分层存储允许我们无缝地将大量数据移动到“对象存储层。这是存储大量历史数据并执行后期分析的绝佳解决方案。如果没有这个,我们将被迫在内部开发解决方案。”
- 一家专有数字资产交易公司的首席技术官
简单性是分层存储的关键特征。要将您的数据从高性能层移动到低成本对象层,您所需要做的就是使用我们的
编者注:时间刻度超表是按时间自动分区的 PostgreSQL 表。这些分区称为块。块是 Timescale 中用户定义策略的单位:例如,当您定义数据保留策略时,您将删除整个分区(块),而当您在存储层之间移动数据时,您将移动整个块。从资源利用和开发人员体验的角度来看,这是一种非常方便的数据管理方法。
例如,此策略会将所有超过一个月的数据移动到events
超表中的对象存储:
SELECT add_tiering_policy('events', INTERVAL '1 month');
这就是您所需要的!其他一切都会自动发生,包括仅在适当层上执行任何 SQL 查询的智能查询计划。
要删除当前存储在低成本存储层中的数据,您可以定义数据保留策略,以便在一段时间(例如五年后)后自动删除数据。
此外,如果您想将特定块从低成本存储层“移回”高性能层(
-- Untier a particular chunk CALL untier_chunk('_hyper_1_1_chunk');
您可以在 Timescale 控制台中跟踪已分层的数据量(以及月底的费用):
说到账单估算……
我们的高性能存储层的有效价格为每 GB/月数据 0.177 美元
分层数据时,您只需为存储的数据付费,而不为执行的查询或扫描的数据量付费:这确实是固定价格。我们采用这种定价结构的目标是提供一种透明、明确且简单的方法来计算总数据存储成本,从而更轻松地管理数据。
举个简单的例子,假设您有一个具有 5.2 TB 存储空间的超表,其中最近的超表块和其他 Postgres 表占用了大约 200 GB 以及大约 5 TB 超过一个月的超表数据。您不会经常访问或查询这些旧数据,这意味着您的应用程序的日常操作不需要它。尽管如此,您仍希望在数据库中保持其可访问性,以便满足临时查询或合规性要求(我们在客户中看到了许多此类案例)。
作为一种经济高效的数据管理策略,您可以将所有超过一个月的数据块分层到低成本层,并将存储 5 TB 数据的成本从每月 478 美元左右降低到每月 105 美元左右,降低了 78%在您的存储账单中。 (对于此估计,我们假设您为超表启用了压缩,并考虑所有 Timescale 服务中的总体压缩中值)。
节省的成本将随着您的数据而增加:当将多个 TB 移动到这个低成本层时,您的存储费用将从数千美元减少到数百美元。下面的参考表说明了我们的低成本存储层实际上是多么经济实惠。
你明白了!
还有一件事让分层存储更加令人惊奇:当您将数据保存在低成本存储层时,您只需为该数据支付一次费用,无论您的服务中是否运行高可用性副本或只读副本。
这同样适用于叉子。在 Timescale 中,您可以通过单击 UI 中的一个按钮来创建主数据库的副本(我们称之为分叉),例如,用于运行测试或创建开发环境。创建一个(或多个)分叉时,您无需为与低成本存储中的主节点共享的数据付费。如果您决定对不在主层中的更多数据进行分层,则需要将其存储在低成本层中,但通过将其从分叉的高性能层移动到更便宜的层,您仍然可以从大量节省中受益。
为了清楚地说明这一点,让我们举一个例子。假设您有一个包含 6.5 TB 数据的主要服务,并且您还设置了:
高可用性副本可显着降低因故障导致的停机和数据丢失的风险
只读副本,用于服务您的读取查询并允许主数据库完全致力于写入
用于开发和测试目的的该服务的分支
从计费角度来看,如果您将 6.5 TB 的数据保留在高性能存储层的主服务中,您会在存储账单中看到 [6.5 TB x 4] 反映在两个副本、分叉和主要服务 — 总共 26 TB。假设我们的中值压缩率,这将是昂贵的:大约 4,602 美元/月。
但是,如果您的应用程序只需要主动访问最近的 500 GB 数据,会发生什么情况?您可以将 6 TB 分层到低成本存储,而在高性能存储层上仅保留 500 GB。由于您只需为低成本存储层中的数据支付一次费用,因此新的存储账单如下所示:
[500 GB x 4] = 2 TB 高性能存储(而不是 26 TB)
低成本存储层 [6 TB x 1]
上述存储费用约为每月 480 美元:您每月将节省超过 4,000 美元!这就是分层存储的节省倍增效应。特别是如果您正在运行副本或分叉,那么利用低成本存储层是一个好主意 - 您将在总体账单中看到的节省将非常可观。
我们于 3 月份在 Timescale 平台中发布了早期版本的分层存储功能,作为抢先体验版。经过多次改进,现已全面上市。自首次发布以来,我们一直努力使分层存储稳定、可靠且更快。
我们还对我们的定价模型进行了长期而深入的思考,不断迭代多种方式来为我们的低成本存储层定价。最后,我们倾向于最简单的方法:对数据量预压缩采用统一费率。我们已经提到过我们如何重视简单且可预测的定价,但对我们来说提供尽可能低的每 GB/月价格也很重要。我们的价格为 0.021 美元——作为比较,在 Amazon S3 上存储文件的成本
就我个人而言,我(Yannis)必须承认,在领导团队构建云原生解决方案十多年之后,我仍然必须回去偶尔重新检查各种云定价页面上的多个费率表,尤其是寻找额外的费用,每次我想准确计算我们服务的总成本。
在 Timescale,我们相信您不必构建复杂的电子表格即可运行数据库服务或对存储层做出明智的选择。
我们致力于让开发人员的生活变得更轻松,这使我们获得了每 GB 每月 0.021 美元的统一费率——没有猜测、隐藏成本或每次查询或数据读取的费用。
预压缩数据量是指应用Timescale压缩之前的数据量。例如,由于 Timescale 压缩,高性能存储层中的 500 GB 卷在压缩后最终可能只需要 50 GB 的磁盘空间。如果您决定将此数据分层到低成本存储,则您的账单将根据原始 500 GB 卷计算,如每月 [500 GB * 0.021 美元]。
插入 Timescale 的所有数据最初都会写入我们的高性能存储层。对最新数据使用更快的磁盘将为您的最新值带来最高的插入和查询性能,这种使用模式适合数据密集型应用程序的需求。
相反,低成本存储层是基于 Amazon S3 构建的对象存储。不过,该对象存储不仅仅是用于存档数据的外部存储桶:它是数据库不可或缺的一部分。当您将数据移动到此对象存储层时,您的数据库将完全了解所有语义和元数据,并且您可以像往常一样使用标准 SQL 进行查询(尽管性能较慢)。
在幕后,我们以压缩的柱状格式(特别是Apache Parquet )存储数据。当数据分层时,块以 Timescale 的本机内部数据库格式存储(通常以我们的
当您运行 SQL 查询时,它将根据需要透明地从高性能存储层、对象存储层或两者中提取数据。当我们说透明时,我们指的是透明:Timescale 支持跨其标准和分层数据的任意复杂查询,包括复杂谓词、JOIN、CTE、窗口、超函数等。
在下面的示例查询(带有EXPLAIN
子句)中,您可以看到当数据库从对象存储层访问数据时,查询计划如何包含Foreign Scan
。在此示例中, devices
和sites
是标准 Postgres 表(仅驻留在高性能存储中),而metrics
是跨两个存储层的超表。当针对metrics
超表执行此查询时,从标准存储读取其三个块,从对象存储读取五个块。
EXPLAIN SELECT time_bucket('1 day', ts) as day, max(value) as max_reading, device_id FROM metrics JOIN devices ON metrics.device_id = devices.id JOIN sites ON devices.site_id = sites.id WHERE sites.name = 'DC-1b' GROUP BY day, device_id ORDER BY day; QUERY PLAN ---------------------------------------------------------- GroupAggregate Group Key: (time_bucket('1 day'::interval, _hyper_5666_706386_chunk.ts)), _hyper_5666_706386_chunk.device_id -> Sort Sort Key: (time_bucket('1 day'::interval, _hyper_5666_706386_chunk.ts)), _hyper_5666_706386_chunk.device_id -> Hash Join Hash Cond: (_hyper_5666_706386_chunk.device_id = devices.id) -> Append -> Seq Scan on _hyper_5666_706386_chunk -> Seq Scan on _hyper_5666_706387_chunk -> Seq Scan on _hyper_5666_706388_chunk -> Foreign Scan on osm_chunk_3334 -> Hash -> Hash Join Hash Cond: (devices.site_id = sites.id) -> Seq Scan on devices -> Hash -> Seq Scan on sites Filter: (name = 'DC-1b'::text)
在上面的查询计划中, Foreign Scan on osm_chunk_3334
对应的是从无底对象存储层获取数据。
为了避免处理落在查询时间窗口之外的块,我们执行块排除以仅触及满足查询所需的块。数据库存储各种形式的元数据,以在对象存储内构建行组和列偏移的“映射”。
此外,当运行查询时,它会对其读取的数据进行进一步的选择性。如果您的查询仅涉及一系列行和几列,则只会从低成本存储层后面的 S3 对象读取该数据子集。
例如,在上面,仅从对象存储层读取device_id
和value
列。如果包含额外的基于时间的WHERE
过滤器,数据库将首先使用其元数据(存储在高性能存储中并缓存在内存中)来进一步减少执行查询时需要读取的 Parquet 文件和行组。所有这些都是为了减少查询延迟,即使通过 PostgreSQL 透明地访问这个无底存储也是如此。
围绕历史数据的存储决策不一定成本高昂。在 Timescale 中,您现在可以访问低成本、无限的存储层,没有定价问题,使您能够以实惠的价格扩展数据库存储,而不会影响应用程序的性能。
如果您想知道这是否适合您的用例,
- 由雅尼斯·鲁索斯、卡洛塔·索托和安娜·塔瓦雷斯撰写。
也发布在这里。