Presto?还是 Hive? 你们知道大数据查询性能谁更强吗?

2020-06-12 12:16:49 浏览数 (1)

技术控们,你们知道大数据查询性能谁更强吗?

经过对 Presto 和 Hive 的性能做了大量的对比测试,最终结果表明: Presto 的平均查询性能是 Hive 的 10 倍!

由于 Presto 的数据源具有完全解耦、高性能,以及对 ANSI SQL 的支持等特性,使得 Presto 在 ETL、实时数据计算、 Ad-Hoc 查询和实时数据流分析等多个业务场景中均能发挥重要的作用。

一、实时数据查询:

我们看看小P在实时数据计算方面又有哪些卓越表现呢?

由于 Presto 卓越的性能表现,使得 Presto 可以弥补 Hive 无法满足的实时计算空白,因此可以将 Presto 与 Hive 配合使用:对于海量数据的批处理和计算由 Hive 来完成;对于大量数据(单次计算扫描数据量级在 GB 到 TB)的计算由 Presto 完成。 Presto 能够完成的实时计算实际上分为以下两种情况。

1. 快照数据实时计算

在这种情况下,可以基于某个时间点的快照数据进行计算,但是要求计算过程快速完成( 200ms~20min)。

2. 完全实时计算

要完成完全实时计算,需要满足以下两个条件。

( 1)使用的基准数据要实时更新,时刻保持与线上实际数据库中的数据完全一致。

( 2)计算过程要能够快速完成。

在某公司的实际使用场景中, Presto 被用于下述两种业务场景中。

  • 基于 T 1 数据的实时计算

在这种业务场景中,用户并不要求基准数据的实时更新,但是要求每次查询数据都能够快速响应。需要 Presto 和 Hive 配合使用来满足实际的业务需求。每天凌晨通过azkaban 调度 Hive 脚本,根据前一天的数据计算生成中间结果表,生成完毕之后使用 Presto 查询中间结果表,得出用户最终所需要的数据。满足该业务场景的解决方案如图

  • 基于 RDBMS 的实时计算

在这种业务场景中,用户要求查询的数据完全实时,即只要业务库中的数据发生改变,通过 Presto 查询的时候,就可以查询到刚刚改变之后的数据。要达到这个效果,我们需要使用合理的机制保证数据实时同步,因此我们使用数据库复制技术,为线上的业务数据库建立实时同步的从库,然后用 Presto 查询数据库中的数据,进而进行计算(请注意:使用官方的 Presto 直接读取数据库的性能还太低,因此建议使用JD-Presto 中的 PDBO 从数据库中读取数据并进行计算)。满足该业务场景的解决方案如图

二、Ad-Hoc 查询

Ad-hoc 查询就是即席查询,即席查询允许用户根据自己的需求随时调整和选择查询条件,计算平台或者系统能够根据用户的查询条件返回查询结果或者生成相应的报表。由此可见,即席查询和普通应用查询的最大不同是:普通的应用查询是定制开发的,其查询语句是固定或者限制在一定的变动范围之内的;而即席查询允许用户随意指定或者改变查询语句或者查询条件。由于普通的应用查询都是定制开发的,其查询语句几乎是固定的,因此,在系统实施时就可以通过建立索引或者分区等技术来优化这些查询,从而提高查询效率。但是即席查询是用户在使用时临时产生的、系统无法预知的,因此也无法对这些查询进行有针对性的优化和改进。

某公司使用 Presto 完成 Ad-Hoc 查询,实际的 Ad-Hoc 使用场景包括以下两种。

( 1)使用 BI 工具进行报表展现

BI 工具通过 ODBC 驱动连接至 Presto 集群, BI 工程师使用 BI 工具进行不同维度的报表设计和展现。由于目前 Facebook 提供的 ODBC 驱动是使用 D 语言开发的,而且功能尚不完善,因此采用 Treasure Data 提供的基于 Presto-gres 中的 ODBC 驱动改造之后的 ODBC 驱动连接到 Presto 集群。

( 2)使用 Cli 客户端进行数据分析

Presto 使用 Hive 作为数据源,对 Hive 中的数据进行查询和分析。众所周知, Hive使用 Map-Reduce 框架进行计算,由于 Map-Reduce 的优势在于进行大数据量的批运算和提供强大的集群计算吞吐量,但是对稍小数据量的计算和分析会花费相当长的时间,因此在进行 GB~TB 级别数据量的计算和分析时, Hive 并不能满足实时性要求。

Presto 是专门针对基于 Ad-Hoc 的实时查询和计算进行设计的, 其平均性能Hive的 10 倍,因此 Presto 更适合于稍小数据量的计算和差异性分析等 Ad-Hoc 查询。

三、实时数据流分析

实时数据流分析主要是指通过 presto-kafka 使用 SQL 语句对 Kafka 中的数据流进行清洗、分析和计算。其在实际使用过程中有以下两种使用场景。

( 1)保留历史数据

在这种使用场景下, 由于 Presto 每次对 Kafka 中的数据进行分析时都需要从 Kafka 集群中将所有的数据都读取出来, 然后在 Presto 集群的内存中进行过滤、分析等操作, 若在 Kafka中保留了大量的历史数据, 那么通过 presto-kafka 使用 SQL 语句对 Kafka 中的数据进行分析就会在数据传输上花费大量的时间,从而导致查询效率的降低。因此我们应该避免在 Kafka中存储大量的数据,从而提高查询性能。

某公司在这种使用场景下,通过使用 presto-hive 与 presto-kafka 配合,完成历史数据的分析和查询。具体系统架构如图所示。

从图中可以看出,对于需要对 Kafka 历史数据进行分析和计算的需求,我们需要配

合使用 presto-hive 与 presto-kafka 完成计算。首先我们先在 Hive 中建立一个分区表,分区表有一级分区,该分区以日期作为分区值。然后在 azkaban 中建立周期性调度任务,在每天凌晨 0 点 0 分准时使用 presto-kafka 将 Kafka 前一天的数据写入到 Hive 的分区表前一天日期对应的分区中,在 Kafka 中只保留最近两天的数据(保留两天的数据,主要是出于容错性的考虑,如果保存的数据是严格的一天,那么将 Kafka 中的数据写入到 HDFS 是需要一定时间的,因此在写入数据的过程中,前一天的某些数据就有可能会被删除了,从而导致数据丢失;另外,保留两天的数据可以在由于一些特殊原因导致写入失败的时候有充足的时间进行人工干预,从而保证数据正确写入)。然后在 Presto 中创建一个 View(视图)用于组合 Hive 中的表和Kafka 中的表,创建视图的语句如下:

在上面的语句中, hive.test.testkafka 是 Hive 中的表,该表用于存储 Kafka 中今天之前的所有数据; kafka.test.testlog3 是针对 Kafka 中 Topic 建立的表,该 Topic 中存储的是最近两天的数据。从上面的语句可以看出: View 其实就是组合的 Hive 中的全表和 Kafka 中当天的数据量,这样 View 中的数据就是实时的最新数据。只需要对业务方开放该 View 的访问权限,业务方就可以通过 Presto 使用 SQL 语句对实时流数据进行分析了。

(2)只保留最新数据

对于只需要在 Kafka 中只保留最近一天的数据,其实并不需要做特殊的处理,只需要在 Kafka 中限制 Kafka 数据的最大保留期限为 24 小时就可以了。然后直接通过 Presto 使用SQL 语句对 Kafka 中的数据进行分析和查询即可。

注意:

在使用 Presto-kafka 对数据进行分析的时候, Presto 是通过 Split 从 Kafka 集群中读取数据的,而 Kafka 中的一个 log-segment 就对应 Presto 中的一个 Split。如果 Kafka 中的一个log-segment 太大就会导致 Presto 中读取的一个 Split 太大,而 Split 个数太少,从而严重降低 Presto 从 Kafka 集群中读取数据的效率。因此在实际应用中,需要适当调整 Kafka 中log-segment 的最大大小,从而保证 Presto 从 kafka 读取数据的效率。

某公司设置 Kafka 中 log-segment 的最大 size 为 128 MB,经过实际验证,效果非常不错。

0 人点赞