使用 MySQL 定期对 100+ GB 的表进行多路连接?

xni*_*kmx 11 mysql rdbms

背景
我创建了一个 Web 应用程序,我希望它能够合理地扩展。我知道我不是 Google 或 Twitter,但我的应用程序为每个用户使用了相当大量的数据,因此对数据的要求相当高。我想准备好进行合理的扩展,而不必在以后重新构建所有内容。

我认为自己是一名软件开发人员,而不是数据库专家。这就是我在这里发帖的原因。希望有更多数据库专业知识的人可以给我建议。

拥有相对大量的用户,但与 Facebook 的数字完全不同,我希望有一个如下所示的数据库:

一张“大桌子”:

  • 2.5 亿条记录
  • 20列
  • 大约 100 GB 的数据
  • 有一个索引 bigint(20) 外键
  • 有一个索引 varchar(500) string_id 列
  • 有一个 int(11)“值”列

其他 4 个表:

  • 每个 1000 万条记录
  • 每个大约 2 - 4 GB 的数据
  • 这些表中的每一个都有 4 - 8 列
  • 一列是日期时间 date_created
  • 一列是 varchar(500) string_id 列
  • 将在连接中选择这些表中的每一个中的一或两列

这些表之一用于存储平均值——它的架构是 bigint(20) id、varchar(20) string_id、datetime date_created、float average_value

我想要做什么——两个相对昂贵的查询:

  1. 计算新的平均值:

    • 使用外键,从大表中选择多达几百万条单独的记录。
    • 计算一个新的平均值,按 string_id 分组。
    • 将结果插入到平均值表中。
    • 按照目前的构造,此查询使用两个连接。
  2. 为服务用户创建非规范化的只读记录:

    • 使用外键从大表中选择 1,000-40,000 条记录。
    • 使用字符串 id 列与最新记录上的其他四个表中的每一个连接。
    • 将结果插入到非规范化表中。
    • 这些记录供前端用来向用户展示信息。
    • 按照目前的构造,此查询使用四个连接。

我计划在批处理后端数据库上运行这些昂贵的查询中的每一个,该数据库将其结果推送到处理用户请求的实时前端数据库服务器。这些查询将定期运行。我还没有决定多久。平均查询可能每天进行一次。非规范化查询需要更频繁——也许每隔几分钟。

这些查询中的每一个当前在 MySQL 中运行在几秒钟内在一个非常低端的机器上运行,数据集在“大表”中有 10 万条记录。我担心我的扩展能力和扩展成本。

问题

  1. 这种方法看起来合理吗?从大局的角度来看,它有什么明显的问题吗?
  2. RDBMS 是正确的工具,还是我应该查看其他“大数据”解决方案,例如 Hadoop 系列中的某些解决方案?我倾向于使用 RDBMS,因为数据是结构化的并且非常适合关系模型。但在某些时候,我的理解是我可能不再能够使用 RDBMS。真的吗?什么时候需要这个开关?
  3. 它会起作用吗?这些查询能否在合理的时间内运行?我可以为查询 #1 等待几个小时,但查询 #2 应该在几分钟内完成。
  4. 从硬件的角度我应该考虑什么?我的 RAM 和 CPU 瓶颈可能是什么?我认为将索引保存在 RAM 中很重要。还有什么我应该考虑的吗?
  5. 在某些时候,我可能不得不对我的数据进行分区并使用多个服务器。我的用例看起来是否已经属于该类别,或者我是否能够在一段时间内垂直扩展一台机器?这可以处理 10 倍的数据吗?100倍?

小智 4

您是否尝试过积累更多数据并对其进行基准测试?100K 行是无关紧要的。尝试 250M 或 500M,就像您期望的那样,您需要处理并查看瓶颈在哪里。

如果您仔细注意其局限性并尝试利用系统的优势,RDBMS 可以做很多事情。他们在某些方面非常擅长,但在另一些方面却很糟糕,因此您需要进行试验以确保其合适。

对于某些批处理作业,您确实无法击败平面文件,将数据加载到 RAM 中,使用一系列循环和临时变量对其进行粉碎,然后转储结果。MySQL 永远无法匹配这种速度,但如果调整得当并正确使用,它可以达到一个数量级。

您需要做的是研究如何对数据进行分区。您是否有一大组数据,其中交叉链接太多而无法将其拆分,或者是否有自然的位置可以对其进行分区?如果您可以对其进行分区,您将不会拥有一个包含一整堆行的表,而是可能拥有许多小得多的行。较小的表和较小的索引往往性能更好。

从硬件角度来看,您需要进行测试以了解平台的性能。有时记忆力是必不可少的。其他时候是磁盘 I/O。这实际上取决于您对数据的处理方式。您需要密切关注 CPU 使用情况并寻找高水平的 IO 等待以了解问题所在。

只要有可能,就将数据分散到多个系统中。如果您有勇气,可以使用 MySQL Cluster,或者只是启动许多独立的 MySQL 实例,其中每个实例使用某种有意义的分区方案存储完整数据集的任意部分。