数据分区:数据分区可用于将表中数据基于hash或range打散到多个存储节点上,配合多副本存储。可以提高数据容灾和迁移效率。除此之外,在查询时可以快速过滤掉不符合where条件要求的数据分区,无需逐列读取数据进行判断。
行组:与数据分区类似,Hadoop中常用的parquet和orcfile还将表数据分为多个行组(row group),每个行组内的记录按列存储。这样即达到列存提高OLAP查询效率,同时能够兼顾查询多行的需求;
局部索引:在数据分区或行组上创建索引,可以提高查询效率。如下图所示,orcfile在每个行组的头部维护了Index Data来,保存最大值和最小值等元数据,基于这些信息可以快速决定是否需扫描该行组。某些OLAP系统进一步丰富了元数据信息,比如建立该行组记录的倒排索引或B+树索引,进一步提高扫描和查询效率。
富元数据:除了提供最大值和最小值信息外,还可进一步提供平均值、区分度、记录数、列总和,表大小分区信息,以及列的直方图等元数据信息。
(7)数据本地化访问
数据本地化读写是常见的优化方法,在Hadoop下也提供了相应的方式。
一般来说,读HDFS上的数据首先需要经过NameNode获取数据存放的DataNode信息,在去DataNode节点读取所需数据。
对于Impala等OLAP系统,可以通过HDFS本地访问模式进行优化,直接读取磁盘上的HDFS文件数据。HDFS这个特性称为"Short Circuit Local Reads",其相关的配置项(在hdfs-site.xml中)如下:
<property> <name>dfs.client.read.shortcircuit</name> <value>true</value> </property> <property> <name>dfs.domain.socket.path</name> <value>/var/lib/hadoop-hdfs/dn_socket</value> </property> br