gpt4 book ai didi

mysql - 我将如何使用 DynamoDB 将此用法从我的 mysql 数据库移动到 nosql?

转载 作者:行者123 更新时间:2023-11-28 23:28:17 25 4
gpt4 key购买 nike

我目前在使用我开发的一项服务时遇到问题,该服务严重依赖于从数据库(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 master,并且 3 r3.8XL 读取只是为了获得我需要的吞吐量容量,以防止应用程序变慢并将 CPU 投入100% 使用率。

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

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

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

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

最佳答案

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

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

旁白:假设您已经有一个关于 (lat,long) 的索引,您可能可以通过添加一个第二个 列反转的索引来获得一些短期性能改进 (long,纬度)。在您的一个复制品上尝试此方法¹,看看是否有帮助。如果您根本没有索引,那当然是您的第一个问题。

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

This is effective checking if the row in question is within the bounding box created by the min / max passed into the where.

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

MySQL spatial extensions支持这种类型的索引。

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

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

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


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


¹ 将索引添加到 MySQL 副本而不是主服务器是一个有效的、受支持的操作,即使在 RDS 中也是如此。您需要通过创建一个与现有参数组相同的新参数组,然后翻转 read_only 来暂时使副本可写。在该组中为 0。将replica关联到新的参数组,然后等待状态从applying变为in-sync,登录replica并添加索引。完成后将参数组放回去。

关于mysql - 我将如何使用 DynamoDB 将此用法从我的 mysql 数据库移动到 nosql?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38410141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com