Hive学习(三)操作Hive的方式及优化

一、操作Hive的两种方式

1、通过Beenline

操作Hive可以直接通过hive命令进入Hive client直接连接HDFS、Yarn进行数据分析以及处理,但是这种方式既不安全也不规范。因此,才有了Beeline,Beeline需要提前与ThriftServer连接,然后进行安全验证,间接的与HDFS、Yarn建立连接,实现解耦。

由于Beeline默认链接hiveserver2的时候也不需要用户名、密码,因此默认方式也是不安全的,但是我们可以设置hiveserver2用户名、密码。

在hive-site.xml配置文件中设置用户名、密码:

<property>
     <name>hive.server2.authentication</name>
     <value>CUSTOM</value>
</property>
       
<property>
     <name>hive.jdbc_passwd.auth.zhangsan</name>
     <value>123456789</value>
</property>
<property>
     <name>hive.server2.custom.authentication.class</name>
     <value>com.hpe.hive.authoriz.UserPasswdAuth</value>
</property>

用户自定义代码进行登录验证:

package com.hpe.hive.authoriz;

import javax.security.sasl.AuthenticationException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserPasswdAuth implements PasswdAuthenticationProvider {
	Logger logger = LoggerFactory.getLogger(UserPasswdAuth.class);

	private static final String USER_PASSWD_AUTH_PREFIX = "hive.jdbc_passwd.auth.%s";

	private Configuration conf = null;

	@Override
	public void Authenticate(String userName, String passwd) throws AuthenticationException {
		logger.info("user: " + userName + " try login.");
		String passwdConf = getConf().get(String.format(USER_PASSWD_AUTH_PREFIX, userName));
		if (passwdConf == null) {
			String message = "沒有发现密码 " + userName;
			logger.info(message);
			throw new AuthenticationException(message);
		}
		if (!passwd.equals(passwdConf)) {
			String message = "用户名密码不匹配" + userName;
			throw new AuthenticationException(message);
		}
	}

	public Configuration getConf() {
		if (conf == null) {
			this.conf = new Configuration(new HiveConf());
		}
		return conf;
	}

	public void setConf(Configuration conf) {
		this.conf = conf;
	}
}

链接Beenline的两种方式:

第一种链接方式:

./beeline -u jdbc:hive2://node01:10000/test -n zhangsan -p123456789

第二种链接方式:

./beeline
!connect jdbc:hive2://node01:10000/test
输入用户名
输入密码

2、通过JDBC

JDBC链接Hive与Beenline链接Hive一样,也是链接hiveserver2服务,链接成功才能操作Hive,为了安全JDBC链接Hive的时候也需要用户名和密码。

package com.hpe.hive.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ConnectHive {

	public static String driverName = "org.apache.hive.jdbc.HiveDriver";

	public static void main(String[] args) {

		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String url = "jdbc:hive2://node01:10000";
		String userName = "zhangsan";
		String passwd = "123456789";
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, userName, passwd);
			Statement statement = conn.createStatement();
			String sql = "select * from test.logtbl limit 10";
			ResultSet resultSet = statement.executeQuery(sql);
			while (resultSet.next()) {
				System.out.println(resultSet.getString(1) + "-" + resultSet.getString(2));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

二、Hive的优化

1、Hive优化的思想:

把Hive SQL当作MapReduce来进行优化。但是查询本表字段、对本表字段进行过滤的SQL语句不会转化成MapReduce来执行。

2、优化的方式

Hive运行方式:

  • 本地模式
  • 集群模式

(1)开启本地模式

set hive.exec.mode.local.auto=true;

但是得满足以下条件才能使用本地模式:

  • 输入数据大小必须小于参数(默认128M)
  • map数必须小于参数(默认4)
  • reduce数必须等于0/1

(2)开启并行计算

set hive.exec.parallel=true;

(3)严格模式

  • 通过设置set hive.mapred.mode=strict;开启严格模式
  • 查询限制
  1. 对于分区表,必须添加where对于分区字段的条件过滤。
  2. order by语句必须包含limit限制。
  3. 限制笛卡尔积的查询。

(4)Hive排序

  • Order By:对于查询结果做全排序,只允许有一个reduce处理 (当数据量较大时,应慎用。严格模式下,必须结合limit来使用)
  • Sort By:对于单个reduce的数据进行排序。
  • Distribute By:经常和Sort By结合使用达到分区排序的效果。
  • Cluster By:相当于 Sort By + Distribute By,但是Cluster By不能通过ASC、DESC的方式指定排序规则。但是可通过distribute by column sort by column asc|desc来进行指定排序。

(5)Hive Join

  • Join计算时,将小表放在左边。
  • Map Join:在Map端完成Join。
    两种实现方式:
  1. SQl方式:在SQl语句中添加Map join标记。
  2. 开启自动的Map joinset hive.auto.convert.join = true;该参数为true时,Hive自动对左边的表统计数据量,如果是小表就加入内存,即对小表使用Map join

相关配置参数:

  • hive.mapjoin.smalltable.filesize;(大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行)
  • hive.ignore.mapjoin.hint;(默认值:true;忽略mapjoin hint 即mapjoin标记)
  • hive.auto.convert.join.noconditionaltask;
    (默认值:true;将普通的join转化为普通的mapjoin时,是否将多个mapjoin转化为一个mapjoin)
  • hive.auto.convert.join.noconditionaltask.size;
    (将多个mapjoin转化为一个mapjoin时,其表的最大值)

(6)Map-Side聚合

设置combinerset hive.map.aggr=true;开启在Map端额聚合。

相关的配置参数:

  • hive.groupby.mapaggr.checkinterval: 默认100000;map端group
    by执行聚合后产生的最大记录数(默认:100000)
  • hive.map.aggr.hash.min.reduction:默认0.5 ;进行聚合的最小比例
  • hive.map.aggr.hash.percentmemory: 默认0.5 ;map端聚合使用的内存占总内存的比例
  • **hive.map.aggr.hash.force.flush.memory.threshold:默认0.9 **
  • map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush;map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush
  • hive.groupby.skewindata;是否对GroupBy产生的数据倾斜做优化,默认为false

(7)控制Hive中Map以及Reduce的数量

Map数量相关的参数:

  • mapred.max.split.size 一个split的最大值,即每个map处理文件的最大值
  • mapred.min.split.size.per.node 一个节点上split的最小值
  • mapred.min.split.size.per.rack 一个机架上split的最小值

Reduce数量相关的参数

  • mapred.reduce.tasks 强制指定reduce任务的数量
  • hive.exec.reducers.bytes.per.reducer 默认 256M
  • 每个reduce任务处理的数据量
  • hive.exec.reducers.max 默认1009每个任务最大的reduce数

(8)Hive - JVM重用

适用场景:
1、小文件个数过多
2、task个数过多
通过set mapred.job.reuse.jvm.num.tasks=n;来设置(n为task插槽个数)

缺点:
设置开启之后,task插槽会一直占用资源,不论是否有task运行,直到所有的task即整个job全部执行完成时,才会释放所有的task插槽资源。

猜你喜欢

转载自blog.csdn.net/qq_42825815/article/details/84193777
今日推荐