在学习hive的时候,就要像说下hive和hadoop集群之间的关系了,
Hive利用HDFS存储数据,利用MapReduce查询数据
hive最适合于数据仓库程序,对于数据仓库程序不需要实时响应查询,不需要记录级别的插入、更新和删除。因此hive不适用于联机事务处理,可以用于联机分析处理。
上图都是来解释hive的一个运行情况,
- 用户可以使用JDBC、ODBC、CLI等连接hive
- 需要开启Thrift Server 服务,这样会将hive当做一个服务器,用户作为客户端连接该服务器处理,
- 通过Driver(驱动模块)对输入进行解析编译
- hive通过JobTracker通信来初始化MapReduce任务(job)
hive的优化
可以从以下几点入手:
-
设置map、reduce、及java堆内存的大小
//每个节点生成动态分区的最大个数,默认是100
set hive.exec.max.dynamic.partitions.pernode=10000;
//一个DML操作可以创建的最大动态分区数,默认是1000
set hive.exec.max.dynamic.partitions=100000;
有时候内存溢出会报错,可以减小set mapred.max.split.size的值(增加map的数量),增加map内存
set mapred.max.split.size=25600000;(切片大小的值不要随意更改)
set mapreduce.map.memory.mb=8192;
set mapreduce.reduce.memory.mb=8192;
set mapred.child.java.opts=-Xmx6144m; -
并行执行
set hive.exec.parallel=true; -
设置中间结果压缩
set mapred.map.output.compression.codec=org.apache.Hadoop.io.compress.SnappyCodec;
如果发生数据倾斜,可以尝试设置此参数
hive.groupby.skewindata=true
-
配置如下参数,可以开启Hive的本地模式(使用本地模式执行可以使hive执行的更快些):
set hive.exec.mode.local.auto=true;(默认为false)当一个job满足如下条件才能真正使用本地模式:
1.job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)
2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)
3.job的reduce数必须为0或者1 -
其他配置
hive.merge.mapfiles; //设置map读取数据是合并小文件
hive.exec.parallel; //任务并行执行
hive.exec.reducers.bytes.per.reducer //多少个字节的数据产生一个reduce
hive.exec.reducers.max //reduce的最大个数
hive.exec.default.partition.name //hive默认分区名字,碰到值为空或者null,数据就到默认分区
hive.exec.mode.local.au0to //决定Hive是否应该自动地根据输入文件大小,在本地运行
hive.auto.convert.join //开关map join模式
hive.groupby.skewindata //数据倾斜 -
还有就是自己电脑的硬件问题了~
hive命令
-
hive执行命令:
hive -e “hql” 可以在命令行执行,并将结果追加至文件中
hive -f filename 可以执行hql文件
hive -f filename -hiveconf project=value hive执行文件传参,语句中使用${hiveconf:project}启动hive的命令:hive
后台启动hive trift服务的命令:nohup hiveserver2 > /dev/null 2>&1 &
启动beeline服务:beeline
使用beeline连接hive:!connect jdbc:hive2://test-hadoop-2-21:10000
使用beeline连接hive,可以使用不同的机器连接同一个hive
显示所有的库:show databases;
显示所有的表:show tables;
显示表结构:desc student; show create table table_name;
显示所有的分区:show partitions student;
清空表:truncate table table_name;
如果存在某个表或库就删除它:drop table exists phone_partition;
重命名表:alter table table_name rename to new table_name;
分区重命名:alter table table_name partition (dt=20180101) rename to partition (dt=20180102);
添加分区:alter table table_name add partition (dt=值);
删除分区:alter table table_name drop partition (dt=值);
修改分区字段类型:alter table table_name partition column (dt string);
添加字段:alter table table_name add column (age int);
修改字段名和字段类型:alter table table_name change age new_age string;
hive元数据存储:通常是存储在关系数据库如 mysql , derby中。
Derby缺点:元数据会生成在hive启动的目录,如果换一个目录启动hive的话,历史数据就访问不到了,会生成新的元数据;只支持单用户访问,如果一个用户启动了hive,其他用户就访问不到了。
hive内部表和外部表的区别:
创建内部表会在HDFS上生成目录,外部表不会;
加载内部表数据会将数据移动到表目录下,而外部表数据一般是在创建表的时候指定一个路径;
删除内部表时会将数据一起删除,外部表不会,