场景:为了优化通过spark sql查询hive中数据的查询效率,在创建表时需要指定压缩方式,将数据压缩,以此提高查询效率。
第一步,查看先前数据占用空间情况:
先前为了比较hive与es的查询效率,因此在数据表中存了恒定的一亿条数据,先查询一下在不进行压缩的情况下数据占用的空间情况,在hadoop的bin目录下执行命令如下:
./hadoop fs -ls /hive-site配置文件下hive.metastore.warehouse.dir的路径|awk -F ' ' '{print $5}'|awk '{a+=1}END {print a/(1024*1024*1024)}'
上述命令其实是计算当前目录下所有数据文件空间大小,单位是GB,最后计算出来,一亿条数据共占用18.9GB
第二步,压缩数据:
在压缩数据之前,需要先在hadoop的bin目录下执行命令:
./hadoop checknative -a
而后所有的压缩方式会打印出来,支持的压缩方式对应是true,不支持的对应false。若出现所有压缩方式都为false,且出现Unable to load native-hadoop library for your platform的提示。需要去hadoop/lib/native是否为空,如果为空需要下载一下hadoop对应版本的库文件,需要先查看一下当前服务器是64位还是32位,要和库文件对应起来,若服务器是64位,库文件是32位的也是会报上述提示。
如果加载了正确的库文件,还是报那个提示,需要检测一下环境变量的设置。执行命令 vim ~/.bashrc,如果没有的话需要加上如下环境变量:
export HIVE_HOME=hive路径
export PATH=$PATH:$HIVE_HOME/bin
export HADOOP_HOME=hadoop路径
export PATH=$PATH:$HADOOP_HOME/bin
而后,创建两个不同数据格式的数据表,语句如下:
create table in_table_compress(
字段
)
partitioned by (day string) //分区
STORED AS PARQUET TBLPROPERTIES('parquet.compression'='SNAPPY'); //数据格式采用parquet,压缩方式使用SNAPPY
create table in_table_compress1(
字段
)
partitioned by (day string) //分区
STORED AS ORC TBLPROPERTIES('orc.compression'='SNAPPY'); //数据格式采用orc,压缩方式使用SNAPPY
然后将先前没压缩的数据表in_table数据同步到刚创建的两个表,由于创建表时建立了分区,因此插入数据时需要指定分区
insert into in_table_compress partition(day=20211019) select * from in_table;
insert into in_table_compress1 partition(day=20211019) select * from in_table;
而后查询一下二者占用的空间大小,使用parquet的达到5.9G,而使用orc的达到了3.8G,可见压缩比还是很高的
第三步,比较查询效率:
分别使用相同的查询语句对in_table(未压缩)和in_table_compress、in_table_compress1进行查询,spark sql语句如下:
select count(*),ip from in_table group by ip having count(*)>5
select count(*),ip from in_table_compress group by ip having count(*)>5
select count(*),ip from in_table_compress1 group by ip having count(*)>5
最后使用8核cpu,8G内存,一亿条数据,同等条件下,分别使用spark执行对上述三个表的查询,时间依次为1.1分钟,37秒和27秒,因此在当前这种情况下使用压缩和分区还是要比不压缩查询效率要高的。