我的名字叫Vitthal。
亚马逊上的Hortonworks HDP 2.4集群是3个数据节点,不同实例上的主节点。7个实例,每个16GB RAM。1TB HDD总空间3数据节点Hadoop 2.7版
我已经将Postgres中的数据拉入Hadoop分布式环境。数据是15张表,其中4张表有1500万张记录,其余为大师。我已经在HDFS中提取了它们,压缩为ORC和SnappyCodec。已创建具有架构的配置单元外部表。
现在,我要启动一个查询,该查询连接所有15个表,并选择最后一个平面表中所需的列。预计记录将超过15亿。
我已经优化了Hive、Yarn、MapReduce引擎,即并行执行、矢量化、优化连接、小表条件、堆大小等。
查询自20小时以来一直在Cluster/Hive/Tez上运行;在最后一个减速器运行的地方,它达到了90%。从18个小时以来,90%一直停留在90%。
我这样做对吗?
如果我理解的话,您已经有效地将原始形式的表从RDBMs复制到Hadoop中,以便在一个或多个新表中创建一个平面视图。你用蜂巢来做这件事。所有这些听起来都很好。
为什么要花这么长时间,有很多可能性,但脑海中浮现出几个。
首先,YARN将分配容器(通常每个CPU核心一个),映射器和reducer将使用这些容器来运行查询的并行部分。这应该允许您利用所有可用的资源。
我使用Cloudera,但我认为Hortonworks有类似的工具,可以让你看到有多少容器在使用,Hive创建了多少映射器和还原器,等等。你应该看到你的大部分或所有可用CPU都在不断使用。工作应该以合理的速度完成(也许每分钟,或者每15分钟)。根据查询的不同,Hive通常能够将其分解为不同的"阶段",这些阶段与其他阶段不同地执行,然后在最后重新组装。
如果是这种情况,一切可能都很好,但您的集群可能资源不足。但是,在抛出更多的AWS实例来解决这个问题之前,请考虑查询本身。
首先,Hive有几个对优化性能至关重要的工具,最重要的是分区。创建表时,应该找到一些方法,将生成的数据集划分为大致相等的子集。一种常见的方法是使用日期,例如年+月+日(可能是20160417),或者如果你希望有很多历史数据,可能只有年+月。这也将允许您显著优化可能受日期限制的查询。我似乎记得Hive(或者可能是YARN)会将分区分配给不同的容器,所以如果你没有看到所有的工人都在工作,那么这可能是一个原因。在CREATE TABLE
语句中使用PARTITIONED BY
子句。
选择日期之类的东西的原因是,假设您的数据在一段时间内(日期)分布相对均匀。在早期的实现中,我们选择了customer_id作为分区键,但随着我们的发展,我们的客户也是如此。数百名规模较小的客户将在几分钟内完成,然后数百名中型客户将在一小时内完成,我们的几个最大客户将需要10个或更多小时才能完成。在最初的一个小时内,我们将看到集群的完全利用率,然后只有几个容器在为最后几个客户使用。不好。
这种现象被称为"数据偏斜",因此您需要仔细选择分区以避免偏斜。有一些涉及SKEW BY
和CLUSTER BY
的选项可以帮助您获得大小均匀或更小的数据文件。
请注意,原始导入数据也应该进行分区,因为分区的作用类似于RDBMS中的索引,因此对性能很重要。在这种情况下,请选择使用较大查询联接的键的分区。有多个分区是可能的,也是常见的,因此基于日期的顶级分区,在联接键上有一个子分区可能会有所帮助。。。大概取决于您的数据。
我们还发现优化查询本身非常重要。Hive有一些提示机制,可以指示它以不同的方式运行查询。虽然与RDBMS相比相当初级,但EXPLAIN
对于理解Hive如何分解查询以及何时需要扫描完整的数据集非常有帮助。很难阅读解释输出,所以请熟悉Hive文档:-)。
最后,如果不能让配置单元以合理的方式进行操作(如果其优化器仍导致不平衡阶段),则可以使用额外的配置单元查询创建中间表,该查询在构建最终数据集之前运行以创建部分转换的数据集。这似乎很昂贵,因为您添加了对新表的额外写入和读取,但在您描述的情况下,总体上可能会快得多。此外,有时使用中间表来测试或采样数据也很有用。
编写配置单元与编写常规软件不太一样——在大多数情况下,您可以很快完成配置单元查询。在少数情况下,让它跑得快需要我们尝试10到15次。祝你好运,我希望这会有所帮助。