parquet和orc_如何通过SparkSQL,Parquet和Alluxio加快即席分析

parquet和orc

在大数据企业生态系统中,涉及分析和数据科学时总是有新的选择。 Apache孵化了许多项目,人们总是对如何选择合适的生态系统项目感到困惑。 在数据科学管道中,即席查询是重要的方面,它使用户能够运行不同的查询,从而产生探索性统计信息,从而帮助他们理解数据。 实际上,对于许多公司和实践而言,Hive仍然是他们的工作之马。 与Hive一样古老,不同的组织可能会以不同的方式破解它,以使其易于使用。 仍然,我听到很多抱怨说查询无法完成。 花时间等待查询执行和调整查询结果会减慢数据科学发现的速度。

就个人而言,与Hive map-reduce程序相比,我喜欢使用Spark来运行即席查询,这主要是由于同时在Spark上执行其他操作的简便性。 我不必使用其他工具来回切换。 最近,我还研究了Alluxio,这是一个分布式的内存文件系统。 在本文中,我将演示使用SparkSQL,Parquet和Alluxio来加速即席查询分析的示例。 使用Spark加速查询时,数据局部性是关键。

使用MapR安装Alluxio

首先,我们从在3节点AWS实例(m4.2xlarge)上运行的现有MapR 5.1系统开始。 我们从Github下载Alluxio并使用Mapr5.1构件进行编译。

git clone git://github.com/alluxio/alluxio.git
cd alluxio
git checkout v1.2.0
mvn clean package -Dhadoop.version=2.7.0-mapr-1602 -Pspark -DskipTests

Oracle Java 8用于编译Alluxio,它也是与MapR系统运行的Java相同的版本。 但是,要启动Alluxio Web UI,需要暂时切换回Java 7。 我们还对配置进行了一些更改,添加了alluxio-env.sh:

ALLUXIO_MASTER_HOSTNAME=${ALLUXIO_MASTER_HOSTNAME:-"node1 host name"}
ALLUXIO_WORKER_MEMORY_SIZE=${ALLUXIO_WORKER_MEMORY_SIZE:-"5120MB"}
ALLUXIO_RAM_FOLDER=${ALLUXIO_RAM_FOLDER:-"/mnt/ramdisk"}
ALLUXIO_UNDERFS_ADDRESS=${ALLUXIO_UNDERFS_ADDRESS:-	"/mapr/clustername/tmp/underFSStorage"}
ALLUXIO_JAVA_OPTS+=" -	Dalluxio.master.journal.folder=/mapr/clustername/tmp/journal"

这些配置将放置在MapR文件系统上的Alluxio文件存储以及主日志中,同时还为Alluxio工作集文件设置5GB的内存。 我们甚至可以在MapR-FS中设置一个专用的卷作为Alluxio的文件系统。 我们还可以添加一个工作文件,其主机名是我们计划在其上运行Alluxio worker的3个节点的主机名。

node1
node2
node3

因此,在我们的3节点MapR集群之上,我们具有Alluxio架构,其中主服务器运行在node1上,工作服务器运行在node1,node2和node3上。 您只需要运行一些命令即可使Alluxio运行。 那么您将可以在节点1:19999处访问Web UI

clush -ac /opt/mapr/alluxio/conf
cd /opt/mapr/alluxio/ 
bin/alluxio format
bin/alluxio-start.sh all

准备数据

为了进行比较,我们还使用CDH-5.8.0构建了一个4节点的Cloudera集群(m4.2xlarge),并将Alluxio放在具有相同架构的3个数据节点上。 我们在两个集群上运行一个独立的Spark shell,在node1上运行spark-master,在node [1-3]上运行3个工作线程,每个工作线程具有10GB的内存。 我们将使用来自Kaggle的点击率预测数据作为我们将要处理的样本数据。 样本数据的大小为5.9GB,包含超过4000万行。 要启动Spark shell,我们使用:

spark-shell --master spark://node1:7077 --executor-memory 2G --packages 	com.databricks:spark-csv_2.1:0:1.4.0

在Spark Shell中,我们从maprfs和hdfs的受尊重路径中加载csv:

val trainSchema = StructType(Array(
    StructField("id", StringType, false),
    StructField("click", IntegerType, true),
    StructField("hour", IntegerType, true),
    StructField("C1", IntegerType, true),
    StructField("banner_pos", IntegerType, true),
    StructField("site_id", StringType, true),
    StructField("site_domain", StringType, true),
    StructField("site_category", StringType, true),
    StructField("app_id", StringType, true),
    StructField("app_domain", StringType, true),
    StructField("app_category", StringType, true),
    StructField("device_id", StringType, true),
    StructField("device_ip", StringType, true),
    StructField("device_model", StringType, true),
    StructField("device_type", IntegerType, true),
    StructField("device_conn_type", IntegerType, true),
    StructField("C14", IntegerType, true),
    StructField("C15", IntegerType, true),
    StructField("C16", IntegerType, true),
    StructField("C17", IntegerType, true),
    StructField("C18", IntegerType, true),
    StructField("C19", IntegerType, true),
    StructField("C20", IntegerType, true),
    StructField("C21", IntegerType, true)
))

val train = sqlContext.read.format("com.databricks.spark.csv")
    .option("header", "true")
    .schema(trainSchema)
    .load(trainPath)

然后,我们将文件写入三次以生成所需的数据:1)以csv格式写入Alluxio,2)以Parquet格式写入Alluxio,和3)以Parquet格式写入HDFS / MapR-FS,因为HDFS / MapR-FS上已经存在CSV格式。

train.write.parquet("maprfs:///tmp/train_parquet")
train.write.parquet("alluxio://node1:19998/train_parquet")
train.write
    .format("com.databricks.spark.csv")
    .option("header", "true")
    .save("alluxio://node:19998/train_crt")

当我们查看文件大小时,我们可以看到Parquet文件的大小更有效。 5.9GB的CSV数据被压缩到小于1GB。

在热数据上运行SparkSQL

现在是时候读取数据并监视不同的性能了。 我将展示Parquet如何提高查询性能,以及何时使用Alluxio很有用。 在读取任何文件之前,我们将删除操作系统缓存,以获得更准确的测量结果。

clush -a "sudo sh -c 'free && sync && echo 3 > /proc/sys/vm/drop_caches && free'"
CSV FILES PARQUET FILES
Cloudera textFile/csv reader Parquet reader
MapR textFile/csv reader Parquet reader

我们可以通过Spark UI捕获执行时间,但是我们也可以编写一个Scala小片段来做到这一点:

val start_time=System.nanoTime()
train.count \\or some other operations
val end_time = System.nanoTime()
println("Time elapsed: " + (end_time-start_time)/1000000 + " milliseconds")

首先,我们在Spark中使用textFile()将CSV数据读取到RDD中,并对CSV文件进行简单计数。 您可能会注意到的一件奇怪的事是,缓存的RDD变慢了。 我要强调一点,因为RDD在缓存到Spark中时压缩不多。 例如,在Spark中,DataFrame /数据集的压缩效率更高。 因此,由于分配的内存有限,我们实际上只能缓存15%的数据,这只是整体的一小部分。 因此,当尝试在缓存的Spark RDD上运行查询时,我们要确保为执行程序分配足够的内存。

Cloudera MapR
TextFile 加快ad-hoc-1 加快ad-hoc-2
TextFile reading Alluxio 加快ad-hoc-3 加快ad-hoc-4
TextFile cached 加快ad-hoc-5 加快ad-hoc-6

其次,我们使用Databricks的包将CSV读取到Spark中的DataFrame中,并对csv文件进行简单计数。 在这里,当将Spark DataFrame缓存到内存中时,我们注意到更好的压缩和更大的提升。

Cloudera MapR
CSV File 加快ad-hoc-7 加速ad-hoc-8
CSV File reading Alluxio 加快ad-hoc-9 加快ad-hoc-10
CSV File cached 加快ad-hoc-11 加快ad-hoc-12

最后,我们将Parquet读入Spark的DataFrame中,并对Parquet文件进行简单计数。 我们可以看到,由于Parquet的出色设计,它对于列式查询非常有效。 另外,它与Apache Drill一起使用时效果很好。

Cloudera MapR
Parquet 加快ad-hoc-13 加快ad-hoc-14
Parquet reading Alluxio 加快ad-hoc-15 加快ad-hoc-16
Parquet cached 加快ad-hoc-17 加快ad-hoc-18

我们可以观察到,利用缓存的DataFrame和RDD可以大大加快查询速度。 如果我们查看任务的执行方式,我们会注意到对于缓存的任务,任务的所有位置级别都显示为“ PROCESS_LOCAL”,而对于非缓存的任务,它们的显示为“ NODE_LOCAL”。 这就是为什么我要说数据局部性是这里查询速度的关键,也是为什么如果您有许多远程数据中心,Alluxio将会成功的原因。 但是您可以通过MapR技术实现类似的想法。 只需为带有热数据的某些卷创建专用的卷镜像,然后将其放置在本地群集上。

加快ad-hoc-19

加快ad-hoc-20

摘要

总而言之,如果我们想加快Hadoop上的查询速度,我们应该真正使用缓存的SparkSQL,并尝试将Parquet格式用于正确的用例。 如果您有远程数据中心或异构存储层,Alluxio会很棒。 它可以提供Spark执行所需的数据局部性。 好处是可以抵御工作失败,并在多个Spark会话之间共享。 为了真正监视系统性能,我们应该监视文件系统的吞吐量统计信息。 这只是性能指标的粗略表示。 我们还观察到,下面的数据越大,使用Alluxio或将其缓存在内存中所获得的好处就越多。

另外,如果您对使用Drill查询Alluxio有兴趣,只需将已编译的alluxio jar文件alluxio-core-client-1.2.0-jar-with-dependencies.jar放在jars / classb下。 您还需要在conf / core-site.xml中添加以下行。

<property>
    <name>fs.alluxio.impl</name>
    <value>alluxio.hadoop.FileSystem<value>
</property>

祝您查询数据愉快! 如有任何疑问,请在下面的评论部分中提问。

翻译自: https://www.javacodegeeks.com/2016/08/speed-ad-hoc-analytics-sparksql-parquet-alluxio.html

parquet和orc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值