hadoop会比mySQL更快

时间:2014-09-22 18:53:24

标签: mysql hadoop hive apache-pig

我面临着一个大数据问题。我有一个庞大的MySQL(Percona)表,它每天连接一次,产生大约250亿行。我试图将所有行组合在一起并聚合以产生结果。该查询是一个简单的连接:

--This query produces about 25 billion rows
SELECT t1.colA as 'varchar(45)_1', t2.colB as 'varchar(45)_2', count(*)
FROM table t1
JOIN
table t2
on t1.date = t2.date
GROUP BY t1.colA, t2.colB

问题是这个过程需要一个多星期才能完成。我已经开始阅读有关hadoop的内容,并想知道map reduce功能是否可以改善处理数据的时间。我注意到HIVE是一个很好的小插件,允许SQL查询hadoop。这看起来很有希望,但我面临的问题是我只能在一台机器上运行:

6-core i7-4930K
16GB RAM
128 SSD
2TB HDD 

当我使用MySQL运行查询时,我的资源是大麦被使用,只有大约4Gb的ram和一个核心只能工作100%而另一个核心工作接近0%。我查了一下,发现MySQL是单线程的。这也是Hadoop看起来很有前途的原因,因为我注意到它可以运行多个映射器函数来更好地利用我的资源。我的问题仍然是hadoop能够在我的情况下替换MySQL,它可以在几个小时内产生结果而不是一周以上,即使hadoop只会在单个节点上运行(虽然我知道它是用于分布式计算)?

4 个答案:

答案 0 :(得分:3)

对你而言,一些非常大的障碍将是hadoop真正意味着在集群上而不是单个服务器上运行。它可以使用多个核心,但它将消耗的资源量将非常大。我有一个系统,我用于测试有hadoop和hbase。它有namenode,secondary name节点,数据节点,nodemanager,resourcemanager,zookeeper等运行。对于单个系统来说,这是一个非常重的负载。另外,HIVE不是RDBMS的真正SQL兼容替代品,因此它必须通过创建map / reduce作业来模拟一些工作。这些作业的磁盘密集程度更高,并使用hdfs文件系统将数据映射到虚拟表中(verbage可能会有所不同)。 HDFS也有相当大的开销,因为文件系统应该分布在许多系统上。

据说我不建议用Hadoop解决你的问题。我建议将来查看它提供的内容。

您是否已查看可以利用多个处理器的数据分片。恕我直言,这将是一个更清洁的解决方案。

http://www.percona.com/blog/2014/05/01/parallel-query-mysql-shard-query/

你也可以考虑测试postgres。它内置了非常好的并行查询支持。

另一个想法是你可能会考虑尝试使用olap多维数据集进行计算,它可以动态重建索引,以便只有更改才会生效。由于您确实在处理数据分析,这可能是一个理想的解决方案。

答案 1 :(得分:2)

Hadoop不是一个神奇的子弹。

Hadoop中的任何东西都比MySQL快,这主要是你编写Java代码(对于Hadoop中的映射器和缩减器)或SQL的能力有多好......

通常,当您在单个主机上运行良好时出现问题时Hadoop会发光,并且需要同时将其扩展到100个主机。如果您只有一台计算机,那么不是是最佳选择;因为它基本上通过磁盘进行通信。写入磁盘不是进行通信的最佳方式。它在分布式系统中流行的原因是崩溃恢复。但是你无法从中受益:如果你失去了你的一台机器,你就失去了一切,即使使用Hadoop。

相反:

  1. 弄清楚你做的是否正确。没有什么比花时间优化您不需要的计算更糟糕的了。考虑使用一个子集,首先弄清楚你是否正在做正确的事情......(很有可能,你的查询首先会出现根本性的问题!)

  2. 优化您的SQL。使用多个查询来分割工作负载。重用早期的结果,而不是再次计算它们。

  3. 减少您的数据。 预计返回250亿的查询必须预计会变慢!生成此大小的结果真的很低效。选择不同的分析,并仔细检查您是否正在进行正确的计算;因为很可能你不是;但你做了很多工作。

  4. 构建最佳分区。通过某个键对数据进行分区,并将每个日期放入单独的表,数据库,文件等等......然后一次处理一个这样的分区(或者如果数据库上有好的索引,只需查询一个键一次)!

答案 2 :(得分:0)

是的你是对的MySQL是单线程的,即每个查询1个线程 只有一台机器我不认为它会对你有多大帮助,因为你可能会使用核心,但是你会因I / O而争用,因为所有线程都会尝试访问磁盘。
您提到的行数很多,但您没有提到磁盘上表的实际大小 你的桌子有多大? (以高清字节为单位表示我的意思)
您还没有提到日期列是否已编入索引。 如果您删除t2.colB或删除所有GROUP BY,它可以帮助您 GROUP BY进行排序,在你的情况下它并不好。您可以尝试在您的申请中执行该组 也许您应该告诉我们您在查询中尝试实现的目标。可能有更好的方法来做到这一点。

答案 3 :(得分:0)

我有一个类似的大型查询,并且能够通过将我的查询分解为多个较小的查询并同时运行它们来利用所有核心。也许你也可以这样做。您可以运行两个(或N个)查询来处理日期的子集,并将结果写入另一个表,而不是处理所有日期的大型查询。

即。如果您的数据跨越2012年至2013年

SELECT INTO myResults (colA,colB,colC)
SELECT t1.colA as 'varchar(45)_1', t2.colB as 'varchar(45)_2', count(*)
FROM table t1
JOIN table t2 on t1.date = t2.date
WHERE t1.date BETWEEN '2012-01-01' AND '2012-12-31'
GROUP BY t1.colA, t2.colB

SELECT INTO myResults (colA,colB,colC)
SELECT t1.colA as 'varchar(45)_1', t2.colB as 'varchar(45)_2', count(*)
FROM table t1
JOIN table t2 on t1.date = t2.date
WHERE t1.date BETWEEN '2013-01-01' AND '2013-12-31'
GROUP BY t1.colA, t2.colB