在巨大的MySQL数据库上运行分析

时间:2012-03-19 20:18:20

标签: mysql hadoop cassandra analytics

我有一个MySQL数据库,里面有几个(准确的五个)巨大的表。它本质上是一个基于星形拓扑的数据仓库。表大小从700GB(事实表)到1GB不等,整个数据库最大可达1TB。现在我被赋予了在这些表上运行分析的任务,甚至可能包括联接。 对该数据库的简单分析查询可以是“查找每个州的吸烟者数量并按降序显示”此要求可以通过简单的查询转换,如

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

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

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

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

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

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

我可以实施其他任何想法吗?

修改

以下是mysql环境设置

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

预先计算值是一种选择,但由于此类ad-hoc聚合值的要求不断变化。

3 个答案:

答案 0 :(得分:2)

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

  • 有没有办法可以分开读写?你每天读书的次数是多少,写的是多少?您是否可以忍受一些滞后,例如每天写入新表并在一天结束时将其合并到现有表中?

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

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

  • 在数据库方面,您使用的是InnoDB还是MyISAM? String列上的索引是什么?你可以把它打成英文等吗?

希望有所帮助

答案 1 :(得分:2)

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

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

话虽如此,我会猜测因为我没有查询计划会发生什么。我猜测(a)你的索引没有被正确使用,你得到了一堆可以避免的表扫描,(b)你的数据库服务器被调整为OLTP,而不是分析查询,(c)在阅读时写入数据导致事情变得非常缓慢,(d)使用字符串很糟糕而且(e)你有一些效率低下的查询加入了可怕的连接(每个人都有其中的一些)。

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

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

  • 将分析查询移出OLTP系统 - 快速插入和短查询所需的调整与可能读取大多数大型表的查询类型的调整非常不同。这可能意味着拥有另一个仅限分析的从属服务器,具有不同的配置(可能还有表类型 - 我不确定MySQL现在的最新状态)。

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

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

  • 如果你在没有解决性能问题的情况下达到这一点,那么是时候考虑离开MySQL了。我首先看一下Infobright - 它的开源/ $$&基于MySQL,所以它可能是最简单的放入你现有的系统(确保数据进入InfoBright数据库,然后将你的分析查询指向Infobright服务器,保持系统的其余部分,完成工作) ,或者如果Vertica发布了Community Edition。 Hadoop + Hive有很多移动部件 - 非常酷(在简历上很棒),但是如果它只用于你系统的分析部分,它可能需要更多的关注和喂食比其他选择。

答案 2 :(得分:1)

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

作为一个底线 - 与MySQL并列的Hive应该是一个很好的解决方案。