【问题标题】:Run analytics on huge MySQL database在庞大的 MySQL 数据库上运行分析
【发布时间】:2012-04-04 08:35:56
【问题描述】:

我有一个 MySQL 数据库,其中包含几个(准确地说是五个)大表。它本质上是一个基于星型拓扑的数据仓库。表大小范围从 700GB(事实表)到 1GB,整个数据库高达 1 TB。现在,我的任务是在这些表上运行分析,甚至可能包括连接。 在这个数据库上的一个简单的分析查询可以是“查找每个州的吸烟者数量并按降序显示”这个要求可以转换为一个简单的查询,如

select state, count(smokingStatus) as smokers 
from abc 
having smokingstatus='current smoker' 
group by state....

此查询(以及许多其他相同性质的查询)在此数据库上执行需要大量时间,所用时间约为数十小时。

该数据库还大量用于插入,这意味着每隔几分钟就会添加数千行。

在这种情况下,我该如何解决这个查询问题? 我看过 Cassandra,它似乎很容易实现,但我不确定在数据库上运行分析查询是否会那么容易,尤其是当我必须使用“where 子句和 group by constructor”时

还研究了 Hadoop,但我不确定如何实现 RDBMS 类型查询。我不太确定我是否想立即投资购买至少三台机器用于名称节点、动物园管理员和数据节点!最重要的是,我们公司更喜欢基于 Windows 的解决方案。

我还考虑过在更简单的汇总表中预先计算所有数据,但这限制了我运行不同类型查询的能力。

还有其他想法可以实现吗?

编辑

下面是mysql环境设置

1) 主从设置 2) 插入/更新的主控 3) slave 用于读取和运行存储过程 4)所有表都是innodb,每个表都有文件 5) string 和 int 列的索引。

预先计算值是一种选择,但由于对这种临时聚合值的要求不断变化。

【问题讨论】:

  • tens of hours?我的天啊!您是否在表上有适当的索引来执行这些查询?
  • @MostyMostacho 是的,我已经创建了索引,您可能会建议将它们加载到内存中,但我的索引本身几乎是 200GB,因此也无法将其加载到内存中。我们还能做什么?
  • 尝试编写更好的查询。利用索引。如果不成功,将 MySQL 数据加载到 RedShift 中,然后聚合。

标签: mysql hadoop cassandra analytics


【解决方案1】:

从试图让 MySQL 更好地工作而不是建立一个全新的架构系统的角度来看:

首先,验证实际情况。解释导致问题的查询,而不是猜测发生了什么。

话虽如此,我将猜测发生了什么,因为我没有查询计划。我猜(a)您的索引没有被正确使用,并且您得到了一堆可避免的表扫描,(b)您的数据库服务器针对 OLTP 而不是分析查询进行了调整,(c)在读取时写入数据导致事情大大减慢,(d)处理字符串很糟糕,(e)你有一些低效的查询和可怕的连接(每个人都有一些)。

为了改进,我会调查以下内容(大致按此顺序):

  • 检查查询计划,确保正确使用现有索引 - 查看表扫描,确保查询确实有意义。

  • 将分析查询移出 OLTP 系统 - 快速插入和短查询所需的调整与可能读取大部分大型表的查询类型的调整非常不同。这可能意味着拥有另一个仅用于分析的从属设备,具有不同的配置(可能还有表类型 - 我不确定 MySQL 现在的最新技术是什么)。

  • 将字符串移出事实表 - 而不是让吸烟状态列的字符串值为(例如)“当前吸烟者”、“最近戒烟”、“戒烟 1 年以上”、“从不吸烟” ,将这些值推送到另一个表中,并在事实表中拥有整数键(这也有助于索引的大小)。

  • 在查询运行时停止更新表 - 如果在查询运行时索引正在移动,我看不到好事情正在发生。 (幸运的是)我已经很久没有关心 MySQL 复制了,所以我不记得你是否可以在没有太多戏剧性的情况下批量写入分析查询从站。

  • 如果您在没有解决性能问题的情况下达到这一点,那么是时候考虑离开 MySQL。我先看看 Infobright - 它是开源的/$$ & 基于 MySQL,所以它可能是最容易放入现有系统的(确保数据进入 InfoBright DB,然后将分析查询指向 Infobright服务器,保持系统的其余部分不变,完成工作),或者 Vertica 是否曾经发布其社区版。 Hadoop+Hive 有很多移动部件 - 它非常酷(并且在简历中很棒),但如果它只用于系统的分析部分,它可能比其他选项需要更多的照顾和喂养。

【讨论】:

    【解决方案2】:

    1 TB 并不是那么大。 MySQL 应该能够处理这个问题。至少像这样的简单查询不应该花费数小时!如果不了解更大的背景,就不会很有帮助,但我可以提出一些您可能会问自己的问题,主要与您如何使用数据有关:

    • 有没有一种方法可以分离读取和写入?你每天读多少,写多少?你能忍受一些滞后,例如每天写入一个新表并在一天结束时将其合并到现有表吗?

    • 您的大多数查询是什么样的?它们主要是聚合查询吗?你能事先做一些部分聚合吗?你能预先计算每天新吸烟者的数量吗?

    • 上面的聚合过程可以使用hadoop吗? Hadoop 在这方面有点擅长。基本上只使用hadoop进行日常或批处理并将结果存储到数据库中。

    • 在数据库方面,您使用的是 InnoDB 还是 MyISAM?是字符串列上的索引吗?你能把它做成整数等吗?

    希望有帮助

    【讨论】:

      【解决方案3】:

      MySQL 有一个严重的限制,阻碍了他在这样的场景中表现出色。问题是缺乏并行查询能力——它不能在单个查询中利用多个 CPU。
      Hadoop 有一个类似于 RDMBS 的附加功能,称为 Hive。它是能够将 Hive QL(类似 sql 引擎)中的查询转换为 MapReduce 作业的应用程序。由于它实际上是 Hadoop 之上的一个小补充,因此它继承了其线性可扩展性
      我建议将 hive 与 MySQL 一起部署,将每日数据复制到那里并对其运行大量聚合。它将卸载 MySQL 的大部分负载。对于通常由索引支持的简短交互式查询,您仍然需要它。您需要它们,因为 Hive 本质上是非交互式的 - 每个查询至少需要几十秒。
      Cassandra 是为 Key-Value 类型的访问而构建的,并且没有内置可扩展的 GroupBy 功能。 DataStax 的 Brisk 将 Cassandra 与 Hive/MapReduce 集成,但将模式映射到 Cassandra 可能并非易事,而且您仍然无法获得 RDBMS 的灵活性和索引能力。

      作为底线 - Hive 和 MySQL 应该是很好的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-31
        • 1970-01-01
        • 1970-01-01
        • 2020-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多