首页 > 解决方案 > DynamoDB 对时间序列数据有好处吗?(市场股票价格示例)

问题描述

DynamoDB 是保存股票价格数据等时间序列的好选择(或者它比普通 SQL 有一些优势)吗?
起初我认为可能会很好,因为数据量很大,而且我们不需要更新或处理它。

问题通常是时间戳将是主键,但如果我这样做,那么我无法使用 DynamoDB 按范围搜索,对吗?
从官方文档中,他们推荐了这个奇怪的东西:
https
://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-time-series.html 基本上使用“日期”(Ymd)作为PK和小时作为排序键。
然后还将不同的日子分成不同的表,并调整读/写的东西。
所以我现在认为在 DynamoDB 中保存时间序列是一个坏主意。

标签: time-seriesamazon-dynamodb

解决方案


大约一年前,我实现了一个相当复杂的系统,用于使用 DDB 作为其底层存储来存储/访问时间序列。为了使事情具体化,假设您要存储与天气相关的数据。您对几个指标感兴趣(“温度”、“湿度”等),并且您可以从多个物理位置收集数据(假设它是城市:“nyc”、“san-francisco”、“伦敦”等)

我用作<location>-<metric>分区键(例如,,"nyc.temprature""london.humidity"和时间戳(自纪元以来的秒数)作为排序键。这导致了以下项目:

{name: 'nyc.temperature', timestamp: 1564617785, value: 35.1}
{name: 'nyc.temperature', timestamp: 1564617786, value: 35.2}
{name: 'nyc.temperature', timestamp: 1564617788, value: 35.1}
{name: 'nyc.humidity', timestamp: 1564617786, value: 0.61}
{name: 'nyc.humidity', timestamp: 1564617788, value: 0.61}
{name: 'nyc.humidity', timestamp: 1564617791, value: 0.62}
{name: 'london.temperature', timestamp: 1564617785, value: 33.8}
{name: 'london.temperature', timestamp: 1564617786, value: 33.8}
{name: 'london.temperature', timestamp: 1564617788, value: 33.9}
{name: 'london.humidity', timestamp: 1564617786, value: 0.11}
{name: 'london.humidity', timestamp: 1564617788, value: 0.12}
{name: 'london.humidity', timestamp: 1564617791, value: 0.12}

这使我能够有效地获取任何给定时间段内任何给定位置的所有温度值(这是读取时间序列数据的典型用例):这是一个简单的 DDB 查询,KeyConditionExpression设置为"#name = :v1 AND #timestamp BETWEEN :v2 and :v3"

更多详细信息

据我所知,不再需要遵循跨分区分散写入的指南。这是由于适应能力的引入。正如这篇文章的标题“您对 DynamoDB 的了解可能已经过时”所指出的,自适应容量极大地改变了人们对跨分区传播密钥的思考方式。为了仔细检查,我还在Twitter 上发布了一个问题并得到了类似的回复。

我的猜测是 AWS 没有更新他们的许多文档页面。这就是为什么你仍然会看到这样的页面使用写入分片来均匀分布工作负载

但是,即使在“旧”(预自适应容量)模式下,即使您不对写入进行分片,您也可以获得相当远的距离。原因如下:

只要您的表大小 < 10GB,您将拥有一个分区,因此分片不会将您的写入分散到多个分区。一旦您的表大小超过 10GB 并为您创建了一个新分区,您将需要购买更多容量。如果您不购买更多容量,您将开始看到限制错误,因此您会注意到这一点。到那时(根据您提供的数据,从您的起点开始大约需要 2.5 到 5 个月),您将更好地了解您的使用模式,并能够对分片方案做出更明智的决定最适合您的需求(是的,您可能需要一些临时容量来防止这些错误。或者,您可以监控表的大小并抢先启动分片)。

例如,如果您拥有的主要是写入而只是偶尔读取(这在许多基于时间序列的应用程序中很典型),那么您可以为写入创建一个表。该表不会超过 10GB,因此您无需担心在其中拆分密钥。一天一次,您可以将数据从该表移动到 X 几个表之一(例如,按当前日期 % X 分片)。在该过程中,您可以压缩数据(将几个项目合并为一个较大的项目),这可能会导致更紧凑的占用空间(因此需要减少容量)。您甚至可以将其移动到 S3 而不是不同的表。无论如何,您可能会对您的阅读模式有更好的了解,从而使您能够设计出最佳的阅读解决方案。


推荐阅读