Amazon Web Services - 如何使用 DynamoDB 将此用法从我的 mysql 数据库转移到 nos



我目前正在开发一项严重依赖数据库(500 行)的大型有效负载读取的服务出现问题。我看到了巨大的吞吐量,在每分钟 35,000+ 个请求的范围内,每个请求通过数据库最多 500 行,它根本没有处理扩展。

所讨论的数据主要在纬度/经度where语句上检索,该语句检查行的纬度和经度是否可以包含在最小纬度经度坐标和最大纬度经度坐标内。这是有效的检查有问题的行是否在由传递到 where 的最小/最大值创建的边界框内。

这是我们依赖的查询 where 部分作为参考。

s.latitude > {minimumLatitude} AND 
s.longitude > {minimumLongitude} AND 
s.latitude < {maximumLatitude} AND 
s.longitude < {maximumLongitude}

所以,话虽如此。MySQL 正在处理这个发现,我目前使用 RDS,不得不严重依赖 r3.8XL 主站,3 个 r3.8XL 读取只是为了获得我需要的吞吐量容量,以防止应用程序变慢并将 CPU 投入 100% 使用率。

显然,随着有效载荷的重量和查询频率,这些数据需要移动到更合适的服务中。类似于Elasticache的服务或DynamoDB。

我一直倾向于 DynamoDB,但我在这里唯一的选择似乎是使用 SCAN,因为我没有有用的主键可以关联到我的数据以减少结果集,因为它依赖于计算点的纬度/经度是否在边界框内。DynamoDB 对属性的筛选条件将非常有效,因为它们支持所需的基本条件,但是在 250,000+ 行且每天增长近 200,000 行或更多的表上将非常昂贵。

减少结果集的另一个选项是使用地图装箱技术将地图区域与数据相关联,并在 dynamo 中将其作为主键,然后进一步筛选纬度/经度属性。不过,这并不理想,我们更愿意在特定范围内获取数据,而不是将多余的冗余数据传回,因为最小/最大纬度/LNG 可以重叠多个箱,然后从可能不需要的引脚中提取数据。

在这一点上,我不得不不断部署只读副本来保持服务正常运行,这绝对不理想。任何帮助将不胜感激。

您似乎忽略了似乎是显而易见的第一件事......使用适合数据性质的索引结构为数据编制索引...在 MySQL 中。

B树的帮助有限,因为在消除另一个维度中不可能的匹配后,您仍然必须在一个维度中检查所有可能的匹配。

旁白:假设您已经有一个索引(纬度,长整型),您可能可以通过添加列颠倒的第二个索引(long,lat)来获得一些短期性能改进。 在您的一个副本¹上尝试此操作,看看是否有帮助。 如果你根本没有索引,那么这当然是你的第一个问题。

现在,实际的解决方案。 这需要MySQL 5.7,因为在此之前,该功能适用于MyISAM,但不适用于InnoDB。 RDS根本不喜欢它,如果你尝试使用MyISAM。

这是有效的检查有问题的行是否在由传递到 where 的最小/最大值创建的边界框内。

你需要的是一个R树索引。 这些索引实际上以理解并保持它们在多个维度上的接近度的顺序存储点(或线、多边形等)。索引中的近点更近,并且可以轻松快速地识别最小边界矩形("边界框")。

MySQL 空间扩展支持这种类型的索引。

甚至还有一个MBRContains()函数,它将索引中的点与查询中的点进行比较,使用R-Tree查找您正在搜索的MBR中包含的所有点。 与通常的优化规则不同,您不应在 where 子句中使用列名作为函数参数以避免触发表扫描,此函数是一个例外 - 优化程序实际上不会针对每一行计算函数,而是使用表达式的含义根据索引计算它。

为了理解

空间扩展的设计,需要一些学习曲线,但是一旦您理解了原理,它就会很好地到位,并且性能将超出您的预期。您需要一个类型为 GEOMETRY 的列,并且您希望将 lat 和 long 一起存储在该索引列中作为POINT

为了在不中断的情况下安全地测试它,请创建一个副本,然后将其与主节点分离,将其提升为自己的独立主节点,并在必要时将其升级到 5.7。 创建一个具有相同结构的新表,加上一个GEOMETRY列和一个SPATIAL KEY,然后用INSERT ... SELECT填充它。


请注意,DynamoDB scan 是一项非常"昂贵"的操作。 在我昨天测试的表格上,无论记录数量如何,每次扫描每次运行时始终花费 112 个读取单元,大概是因为扫描始终读取 1MB 的数据,即 256 个 4K 块(读取单元的定义),但一致性不强(因此,成本只有一半)。1 MB ÷ 4KB ÷ 2 = 128,我认为这足以接近 112,这解释了这个数字。


¹ 即使在 RDS 中,将索引添加到 MySQL 副本而不是主副本也是受支持的有效操作。 您需要通过创建一个与现有参数组相同的新参数组,然后将该组中的read_only翻转为 0 来临时使副本可写。 将副本关联到新参数组,然后等待状态从"应用"更改为"同步",登录到副本并添加索引。 完成后,将参数组放回原处。

相关内容

  • 没有找到相关文章

最新更新